Become a fan of Slashdot on Facebook


Forgot your password?
Perl Books Media Programming Book Reviews

The Perl Black Book 41

Reviewer Greg Smith here dissects a book aimed at programmers who want to add Perl to their stable of languages, but also useful to the Perl connoisseur. If your interest in Perl is more than casual -- especially if you're seeking practical code examples more substantial then in more introductory texts -- The Perl Black Book may be for you. (Read more.)

The Perl Black Book
author Steven Holzner
pages 1283
publisher Coriolis
rating 7/10
reviewer Greg Smith
ISBN 1-57610-465-6
summary Perl introduction and reference guide with lots of example code, targeted at those already familiar with another programming language.

The Scenario

You already know C or BASIC or some other programming language, but there's some work you need to finish that none of these languages are the right tool for. Perhaps you want to create CGI programs. The Perl Black Book is an excellent choice to fill that need. It's a non-nonsense title that's focused on working example code in a form that will be familiar to those stepping from another programming language into Perl.

What's Bad

While the book is large, the scope of material it attempts to cover is considerably larger. Coriolis labels the book as intended for intermediate to advanced materials, and there's a minimum of introduction to general programming concepts. Non-programmers trying to learn Perl as their first language would be better served starting with a more introductory title and coming back to this book later. And while there are examples of things like object-oriented Perl and CGI, none of that material goes deep enough to really satisfy a serious student of those topics.

The most annoying thing about this Coriolis release is the introduction to most sections. Holzner spins these little stories about a Novice Programmer, his Big Boss, a Programming Correctness Czar, and other random characters to suggest why you'd need to know about a topic. I question the necessity of these motivational interludes, as they take up space, waste my time reading them, and offer very little in return. The kind of person I'd expect to be reading this book doesn't need a little story suggesting why you'd want to be able to format text when you print it; that this is a useful thing to learn is pretty obvious.

What's Good

The Perl Black Book does an excellent job with the kinds of things intermediate programmers in the language are interested in. It's become the first place I turn to when looking for a snippet of Perl code to incorporate into a project. An example of why I like this book should illustrate why that is. I recently found myself writing a program that needed to ping a host and take some corrective action if that ping was unsuccessful. I would expect this is a straightforward request, and looked up "ping" in the index of O'Reilly's Programming Perl. This led to an example using the pingecho library call, which I typed in and found utterly unsuccessful at the task I was trying to accomplish. Looking up the same topic in the Perl Black Book, I found a section about twice as large on the subject. Holzner's example program worked just as I was expecting, and I went back to the rest of the application design without needing to focus for very long on the implementation details of this small piece. I've never liked the code in Programming Perl because the samples are all so terse. The Perl Black Book does a much better job in my view of providing programs long enough to demonstrate the appropriate Perl syntax for filling common needs.

So What's In It For Me?

Since so much Perl programming is done in the context of a CGI script, many chapters of this book are devoted to that topic. The majority of the material revolves around using Lincoln Stein's library. Much of this mimics Stein's own book, Official Guide to Programming with, but instead of the reference-guide approach, there's more of an emphasis on practical solutions for regularly recurring requests. Example code shows how to create Web counters, guest books, e-mailers, chat, shopping carts and other popular items. A single chapter also introduces usage of the older to create basic HTML pages, but the main focus is definitely, using all of its abstraction. While the CGI section is substantial, considerably more so than the average Perl programming book, there are a number of areas that will need supplementation before you'd want to create a production system. The discussion of the taint mechanism for security is a bit weak, and the basic information about cookies and hidden fields doesn't really give an impression of how to build a larger-scale Web application and properly save state along the way. That is, to be fair, outside of what I'd expect a Perl book cover, and it's only because most of the other material so is helpful that these weaker areas stick out.

The Perl Black Book provides plenty of the kind of examples I'm looking for when writing a Perl program, and it's large and comprehensive enough to cover most areas in sufficient depth. The real question is whether it meshes well with your approach to the language. Holzner is obviously aiming this title at someone who is learning Perl as their second, third, or nth programming language. The samples avoid relying on Perl-specific idioms in most cases. Personally, I find this approach refreshing, as programs I write in Perl frequently end up getting ported to another language later, or co-opted by another programmer who isn't as familiar with the language. So for me, writing Perl that embraces too heavily Perl's language specific features leads to portability and maintenance problems later. For example, when I read through Randal Schwartz's Learning Perl, by page 11 he's already using regular expressions to match strings. I find myself wanting to use a more traditional substring/comparison operation in that context instead, because I know that code will port to any other language easily, and any competent programmer will understand what I'm doing regardless of their familiarity with Perl. Holzner understands that mindset, and writes his prose and programs accordingly; witness the following tip from P291:

"The line ++@_[0]; is a cute example of why nonprogrammers think Perl is obscure. Try showing that line to your grandmother and explaining that you write stuff like that for a living."

If you look at the example above and think that's a nice way to use Perl, by all means stick to the traditional books on the topic from Schwartz, Larry Wall and Tom Christiansen. But if you think that line is unnecessarily cryptic, I think you'll be impressed with how little material like that is inside Holzner's Perl Black Book. It doesn't try to embrace "The Perl Way," but it is a quite useful resource when you're on a short deadline to deliver a working program and don't have time to absorb too much of the language to do it. I'm buying a second copy for the office this week because mine keeps walking away, and there's no greater recommendation for a computer title than noting that copies of the book disappear regularly.

Purchase this book at ThinkGeek.

Table of Contents

  1. Essential Perl
  2. Scalar Variables and Lists
  3. Arrays and Hashes
  4. Operators and Precedence
  5. Conditional Statements and Loops
  6. Regular Expressions
  7. Subroutines
  8. Formats and String Handling
  9. References
  10. Predefined Variables
  11. Built-In Functions: Data Processing
  12. Built-In Functions: I/O
  13. Built-In Functions: File Handling
  14. Built-In Functions: Interprocess Communication
  15. Standard Modules
  16. Perl/Tk--Windows, Buttons, and More
  17. Data Structures and Databases
  18. Debugging and Style Guide
  19. Creating Packages and Modules
  20. Creating Classes and Objects
  21. Object-Oriented Programming
  22. Internet and Socket Programming
  23. CGI Programming:
  24. CGI Programming With Other Popular Package
  25. CGI: Creating Web Counters, Guest Books, Emailers, and Secure Scripts
  26. CGI: Creating Multiuser Chat, Server Push, Cookies, and Games
  27. CGI: Creating Shopping Carts, Databases, Site Searches, and File Uploads
  28. Handling the Web in Code
This discussion has been archived. No new comments can be posted.

The Perl Black Book

Comments Filter:
  • List $49.99US, $39.99Amazon....
  • Alright, I'm going to look ignorant. But
    what DOES ++@_[0]; do?

    As for the comment on trying to use traditional substring functions, all I have to say is that I
    love regular expressions. Several years ago, I was writing a web server log analysis program for a turnkey e-commerce package. I did not know regexps, and I was required to write in C. I ended up coming up with a half-brained conception of regexps and trying to write my own (buggy) module to handle them. When I later learned PERL and regexps and discovered there was a regular expressions package for C, I mourned for months of lost youth. Sigh...
  • ++@_[0]; will increment the first argument that a subroutine is given.

    ++$var; will add 1 to $var, @_ is the array where arguments are stored, and @array[0] will be the first member of an array.

    Hope this helps demystify Perl a little for you!
  • about ++@_[0]; @_ is a special Perl variable that holds any arguments passed to a function, so ++@_[0]; should increment the first argument by one.
  • $30.95 - []
  • by ruud ( 7631 ) on Thursday May 11, 2000 @07:24AM (#1078345) Homepage
    For this construct, perl -w reports:

    "Scalar value @_[0] better written as $_[0]"

  • After I purchased this book a few months ago I found a number of errors in it. I contact the publisher, so you may want to check the errata on their site of they have a section for it.

    Perl In a Nutshell is probably a superior reference volume to this book, and of course Programming Perl is the definitive tutorial.

  • by Anonymous Coward
    As a general rule, I have found the coriolis books to be extremely useful. For the most part, they're easy to read and follow, as described in the review. Of course, I make no claims to be uber-geek so I don't miss the advanced programming information that these books generally dont conver, either.
  • ...when I read through Randal Schwartz's Learning Perl, by page 11 he's already using regular expressions to match strings.
    Well, yes - we're learning Perl here, so we start on regular expressions quickly, 'cos they're the good bit. You might want to use substrings and comparisons, but the example he gives is to match a string which begins 'Randal', has a word boundary after that, where case is unimportant. Hack together something that does that in another language --- I bet it won't be as compact and neat as '$name =~ /^randal\b/i' unless that language supports regexps too.
  • IANAPH, (well, I've done a little bit), but surely the the whole point of Perl is that it's obfuscated and hard to understand?

    Actually, that sounds a bit strange... it seems to me that Perl is very programmer-oriented, rather than mantainer-oriented, what with TMTOWTDI an' all; the ability to write powerful programs quickly seems to be more valued than for someone to come along and understand it. If I was writing some code for a large project that needed to be quickly understood, I'd do it in Java or something.

  • I think the compiler has a point.

    I'd bet ++$_[0]; is the correct way to write that example statement. But then again the author was probably trying to make an entirely different point.

  • I agree with the reviewer that the examples in Programming Perl can be terse, and don't always work like expected. More than once I have had to hack at their code examples and/or load more modules from CPAN to get them to work. But then, if it wasn't for that, I wouldn't really be learning anything at all about Perl, I'd just be cutting and pasting code....I'm glad for the terse and cryptic examples. They give me a reason to think.

  • Yes, I'm replying to my own post. But just so everyone knows exactly how this works, here's an example:

    #!/usr/bin/perl -w

    my $i=5;

    sub DoSomething () {
    print ++$_[0];

    ~> ./inc
  • I've found a good search engine to be the
    best reference.

    Take the cost of most any programming
    manual and compare it to the cost of
    one month's internet service.

    The cost of the book is roughly 1.5 months
    of internet service.

    Or, if you are like me, do it at work for free!
  • by alleria ( 144919 ) on Thursday May 11, 2000 @07:59AM (#1078354)
    The samples avoid relying on Perl-specific idioms in most cases. Personally, I find this approach refreshing ...

    I find myself wanting to use a more traditional substring/comparison operation in that context instead, because I know that code will port to any other language easily, and any competent programmer will understand what I'm doing regardless of their familiarity with Perl.

    [Holzner's Perl Black Book] doesn't try to embrace "The Perl Way" ...

    I see. So it's a book for programmers from other languages who don't really want to learn Perl. That's too bad. Can you imagine a ANSI C++ book that decided that because the STL was rather idiomatic and specific to C++, that they simply weren't going to cover it?

    And what's this about having 'any competent programmer will understand ... regardless of their familiarity with Perl'?? Excuse me: when I write in English, I really don't try to use the Latin subset of English that happens to be the interesection of all Latinate languages, just so that a French speaker can understand my English. So why, when I decide to write Perl, should I write for a Smalltalk or Eiffel programmer?

    By writing Perl with syntax and conventions from other language (so that you can port), you defeat the entire purpose of using Perl as your language.

    I mean, why WOULD you use Perl, if you were just going to write stuff that looks like a bad approximation of C++ or Java code, and then just port it later? Sounds like the worst of both Perl and your other language, in that case!

  • Don't buy a book without checking out [], a website which automatically compares the price of a given book at 29 different online bookstores. No I don't work for them ...
  • ++@_[0]; isn't only an example of something grandmothers think is implausible - your average language designer is likely going to have fits over it too.

    And it's definitely not cute. It's reminiscent of sendmail. It's pretty ugly.

    I'm planning to learn perl basics, but not because it's a good language. I'll be doing it because there are so vastly many misguided souls who insist on using it, and I can no longer avoid their code.

    In short, there are entirely too many programmers in the world who think that if their code is hard to read, that makes them clever - when in fact the reverse is true. A truly excellent programmer takes a difficult problem, and writes code to implement it in a way that makes it relatively easy for maintainers to understand.

  • @array[0] is a one-element hash slice ($array[0] is the first member of @array), and the pre-increment only does the obvious thing because it is a one-element slice. This is bad programming style, and horribly confusing, not idiomatic Perl. Idiomatic Perl is about saving typing and running time by using shortcuts, and this does neither (array lookups are slower than scalar lookups, as well as the same number of characters to type). Without the context for this statement, however, who knows what it's author meant.

    By the way, ++@_[0,1] (a two-element hash slice) increments only $_[1] (the last value).


    Cthulhu for President! []

  • The whole point of Perl is to make it possible to write both ways, as well as up-and-down and sideways. I can write very quick and very dirty code that does a job fairly well. I can also write elegant code that's clean and understandable by someone of decent Perl ability.

    Granted, there is a lot of the former roaming around (stuff that doesn't even compile under the strict pragma and that generates pages of warnings with -w enabled), but there are people like me, who write Perl every day, turning out good and clean code.

    Would you say that Stephenson can't write excellent prose in English after reading a few pages of script-kiddie leet-speak in IRC?


  • Actually, the reviwer is right, both Perl AND VB belong in a stable of programming languages. That doesn't mean they're fit for human consumption, though.
  • I sympathize somewhat with a reaction against "the Perl Way"; it's certainly easy to write write-only code in Perl. But if you're thinking about using character indexing to break apart strings, you're using the wrong tool. Sure, you *can* write such code in Perl, but it's going to take longer, be more error prone, and be tougher to read. To use the power of a language, you need to adopt the proper idiom. Just like I expect C programmers to use pointers to char rather than indexing then as an array, I expect Perl programmers to use regular expressions to break string rather than index and substr. If you're not going to use regex, why are you using Perl?
  • I actually used this book to learn PERL, and I must agree with the reviewer's comments. I liked the amount of subject matter it included and the numerous examples.
    The book also features a very complete index which many people take for granted but is essential for a good reference book.
    Like the reviewer, I also found the 'stories' at the beginning of the chapters to be very tedious and annoying.
    I was also disappointed in some of the stuff that the author seemed to skip over. One thing in particular that I noticed was the lack of dealing with tables in CGI.
    Overall, I'd have to say I was satisfied with the book, and as a newbie to PERL I learned a lot from it. It also seems to make a very handy reference.
    Of course, this is all IMHO.
  • by RubiCon ( 158847 ) on Thursday May 11, 2000 @11:13AM (#1078362) Homepage
    I've always been a fan of Perl because it maps to the way I think - when I concoct solutions in my head, I think in the same kind of atomic units that Perl (and Tcl, for that matter) uses.

    The problem here is that writing a Perl book designed specifically to shoehorn a C-thinking (or worse yet a VB-thinking) mind into a Perl-mindset is never going to hit the mark. Ultimately, to make that transition, you have to be willing to ditch a lot of the coding intuition that you've built up.

    The Camel Book understands this and starts by teaching the lesson of TMTOWTDI and by belting you with regexps as soon as it possibly can. A book that tries to mollycoddle and tell you you don't need rethink your coding strategy is probably never going to tap the full potential of Perl.

    Oh, and I'd hope no Perl hacker worth their salt has ever used ++@_[0]; - but then, I suppose


    is confusing enough for non-Perl-thinkers. ;)
  • In general, I'd agree with you, but there are actually many instances where index() and substr() work much better than regexes. They're faster too. It's very unfortunate that so many Perl programmers don't know how to use them - and at DALNet #perl we usually try to encourage people to use these functions instead of hacking up a regex-based kluge.

    An example, just OTTOMH: say you're reading in a pipe-delimited file, where you want to grab only the second field (which, say, holds a "name" field). Compare the two approaches:

    push(@names, substr($_, ($a = index($_, '|')), index($_, '|', $a + 1))) while <>;

    push(@names, split('|')[1]) while <>;

    Sure, the second one is smaller, but it's slower and takes up more memory - for chrissakes, it has to split the entire line just to grab the second piece!

    Here's another ubiquitous use of substr() - the somewhat obligatory quine, in the traditional AqABqB format:

    $_ = '$_ = ; print substr($_, 0, 5), chr(39), $_, chr(39), substr($_, 6, 66);'; print substr($_, 0, 5), chr(39), $_, chr(39), substr($_, 6, 66);

  • I dunno - I think $a[0] makes more sense than @a[0]. Anytime I see @, I expect to be dealing with more than one value. @a[0] tends to make me think there's an array stuffed in there (which would of course be @$a[0], but the half second of confusion slows me down).

  • Excellent example. That perl is a write-only language is an accusation that gets thrown at perl far too often, when it's really the programmer's goddamned fault.

    Unless I'm just throwing a few lines together to mangle something on my own machine, I'm very careful about how I write my code. Not that anyone else has to look at it, but I frequently have to come back to it six months later. And I guarantee there's no way in hell I'll remember what I was thinking.

    On the other side, I recently had to cobble something together for what I was promised was a one-time-only affair on a tight deadline. I made the conscious decision to write the quickest, dirtiest, I-don't-give-a-damn-so-long-as-it-compiles code I could, just to get the job done.

    Now I understand the siren call that has for some - I was amazed at how fast I could put together a medium-complex CGI if I didn't worry about such petty things as commenting and legibility.

    God it was ugly.

    A week later, the powers that be mentioned that we'd be doing the same thing next year, and great, we've got the code now. I didn't bother pointing out that wasn't the deal. I just wiped all my copies.

  • I've been using the Perl Black Book for a couple months now. There are a lot of things that are handled well, but a few annoyances.

    I agree with the review that object-oriented and CGI programming are undercovered. Also, it doesn't give a single example of CGI which isn't object-oriented - and I don't always want to use that method in my scripts.

    Also, regular expressions are almost impossible to understand with this text alone. For example, the first example of a regex in this book is:

    if ($text =~ /[\w\s.]+/i) {print "Found an image or anchor";}

    Call me crazy, but that sounds like something I want to work up to, not start with.

    Also, the little text blerbs about the Programming Correctness Czar are really pretty funny and occasionally helpful. The reviewer is clearly a humorless bastard.
  • Arrgh.
    That example was:

    if ($text =~ /<(IMG|A)>[\w\s.]+<\/\1>/i) {print "Found an image or anchor tag.";}

  • AFAIK, even Larry Wall doesn't recommend you write something like this. One can write readable Perl and unreadable Perl, just as you can write readable C++ and unreadable C++.

    Anyway, wot's wrong with ++@_[0] ?
    (IIRC, preincrement the first argument).

    That said, Perl does offer more opportunities to make your code unreadable; perhaps this is a downside of TMTOWTDI (There's More Than One Way To Do It). Another is that TMTOWTDI leads often to WFWSIDI (Which Fsking Way Should I Do It ?). From the sound of the review though, I'll stick with the good 'ol Camel book from O'Reilly.
  • by nakaduct ( 43954 ) on Thursday May 11, 2000 @01:27PM (#1078369)
    there are actually many instances where index() and substr() work much better than regexes

    Yes, though you failed to provide an example. I benchmarked the example you gave (using a 16000-line passwd file as the source), and (higher numbers are better):

    • index: ... @ 160060.30/s (n=536202)
    • regex: ... @ 165649.72/s (n=499710)
    • split: ... @ 152474.50/s (n=536202)

    The code: (use view source to get the line breaks and diamond):
    #!/usr/bin/perl use Benchmark; @pw=; # give source file name on cmd line timethese -3,{ 'index' => 'my @n=map { substr $_,($a=index $_,":"),index($_,":",$a+1) } @pw', 'split' => 'my @n=map { (split ":",$_,3)[1] } @pw', 'regex' => 'my @n=map { (/^[^:]*:([^:]*):/)[0] } @pw' }

    ... all within a few percent, and the Perl Way solution (using pure regexes) is still faster than the {large,inflexible,confusing} index/substr method. Getting the fourth field means the logic has to change (and, I'll wager, the performance "gain" evaporates). Handling escaped delimiters is a major pain. And so on.

    In my experience, when choosing between the Perl way and an old-school algorithm-textbook way, the Perl way:

    • Will run in the same time complexity (maybe *lgN, especially when hashes are involved), and with a negligible constant cost.
    • Will be easier to write.
    • Will be easier to read.
    • Will be highly adaptable to changes, often without rewriting -- regexes written with ambiguity in mind are particularly good at handling changes in input formats.
    • Will use more memory. This really is Perl's Achilles' Heel. The only time I've had to use tactics like you describe is when iterating over huge input files (~10M lines) -- if the garbage collector isn't perfect (and it isn't) the accumulated leakage will kill your program.

    So, forget about 1% performance variations. Concentrate instead on the benefits of solving problems in half the time, and of having written code that someone less-brilliant than yourself can maintain.


  • (split '|')[1] does NOT need to "split the entire line" to grab the second piece:

    perldoc -f split

    The LIMIT parameter can be used to split a line partially

    ($login, $passwd, $remainder) = split(/:/, $_, 3);

    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 list above LIMIT would have been 4 by
    default. In time critical applications it behooves you not to split
    into more fields than you really need.

    To be honest, the substr version makes my head hurt to read, and I'd be suprised if it were any faster.

    Also, assigning and using $a in two different arguments to the same subroutine makes me stop and think for a long time, and frankly meat time is infinitely more valuable than silicon time to me...

    I'm much more inclined to call index/substr a kludge in this case.
  • well a couple of people have corrected your assumption that substr/index was better/faster. I just wanted to point out that your quine was buggy :)

    It should be:

    $_ = '$_ = ; print substr($_, 0, 5), chr(39), $_, chr(39), substr($_, 6, 66);'; print substr($_, 0, 5), chr(39), $_, chr(39), substr($_, 5, 66);

  • Yes, you read that right. Compared to Perl Black Book, O'reilly has nothing that comes close. Programming Perl can't even manage to get an emulated switch/case to work right.

    I'd give it an 10/10 for usefullness, a 7/10 for organization, and an 8/10 for correctness (overall 8/10) as I've never had anything from that book be wrong (contrary to the Programming Perl book), but there is a horrible miss-print in my book where a good portion of the string handling pages are reprinted.

    If you must have just one Perl book, this is the one.

  • There _is_ a difference between a hash slice and a list slice, you know...
  • I'd agree with you entirely, and this bit:

    I find myself wanting to use a more traditional substring/comparison operation in that context instead [of regexps], because I know that code will port to any other language easily, and any competent programmer will understand what I'm doing regardless of their familiarity with Perl

    sounds daft. I am not a Perl programmer. I know perfectly well what a regexp looks like. I don't see how one can be competent to deal with string parsing code unless one understands regexps. Not only is the guy losing out on the Perlishness of Perl, he is losing out on anything remotely interesting! I don't think it's valid to refrain from coding anything complicated, ever, just in case one's successors are dozy. If I was porting code with regexps to C++, guess what, I'd get a C++ library with regexps in! There's a difference between using powerful language features and putting incomprehensible language warpings in just to impress people.

  • It should be:

    $_ = '$_ = ; print substr($_, 0, 5), chr(39), $_, chr(39), substr($_, 6, 66);'; print substr($_, 0, 5), chr(39), $_, chr(39), substr($_, 5, 66);

    Uh... maybe I'm missing something here... but isn't that exactly what I posted? (Except that mine was pretty-printed, of course...)
  • But what DOES ++@_[0]; do?

    Well, it issues a warning. ;-) It's a classic mistake made by people unfamiliar with programming in Perl. If this code is really in the book, it's a bad sign.

    -- Abigail

  • push(@names, substr($_, ($a = index($_, '|')), index($_, '|', $a + 1))) while ;

    That assumes an order of evaluation that isn't garanteed.

    Sure, the second one is smaller, but it's slower and takes up more memory - for chrissakes, it has to split the entire line just to grab the second piece!

    Nope, it doesn't. (split /\|/, $_, 3) [1]; will do fine.

    -- Abigail

  • if ($text =~ /<(IMG|A)>[\w\s.]+<\/\1>/i) {print "Found an image or anchor tag.";}

    Well, that doesn't make much sense. First of all, IMG isn't a container, so it will not have a close tag. Second, in HTML, tag names are case insensitive, you can use A in your opening tag, and a in your close tag. This regex doesn't cover that. But worse is the [\w\s.]+ part, indicating the author doesn't know regex syntax. It asks for one or more letters, numbers, underscores, white space characters or periods. But typical HREF or SRC attribute values will contain slashes, colons, and are contained in quotes.

    If this is indeed in the book - think twice before buying it.

    -- Abigail

  • And I stand by my statement. None of the Perl books (including Learning Perl) is any good for anything other than a reference when you compare it to Perl Black Book. And Perl Black Book is substantially better as a reference book than any of the others. Perl Cookbook is OK for canned solutions, but it's not terribly useful if you fall out of its area of coverage.

  • While this book may beat Programming Perl in the examples department, that doesn't surprise me at all.
    O'Reilly's book covering code examples would be the Perl Cookbook, which does a fairly good job demonstrating how to ping a machine (section 18.7 in the book). Programming Perl is more of a reference for how functions work.

VMS must die!