New Book: Core Perl

pudge on 2002-01-02T20:18:00

Reuven M. Lerner writes "My new book, Core Perl, was just published by Prentice Hall, and is available at most online bookstores. A sample chapter (on modules) is here.

The book begins with an overall introduction of Perl (data structures, regexps, built-in functions, subroutines, modules, and objects), moves onto a discussion of databases (using PostgreSQL for examples), describes CGI programming, and then concludes with two chapters about mod_perl and Mason. There is also a chapter on program maintenance and debugging, since many new Perl programmers fail to appreciate all of the good stuff that the language offers in this regard.

Core Perl is meant to introduce people to Perl (but not to programming), and is based on the many questions and issues I've seen people struggle with during my years as a trainer and Web/database consultant."


Something odd in the sample chapter

po_boy on 2002-01-02T23:23:14

I notice that one of the first examples of code in the chapter available online includes this:

#!/usr/bin/perl
# filename: counter.pl

use strict;
use warnings;

# Declare $counter lexical within the foreach loop
foreach my $counter (0 .. 10)
{
    print "Counter = $counter\n";
    $counter++;
}

# $counter has disappeared -- fatal compilation error!
print "Counter at the end is $counter\n";

I was wondering why $counter is incremented. I thought that would be taken care of as it loops over (0 .. 10). Is that something that is included just to make the point easier to see, or a typo, or does it do something that is not obvious to me?

Re:Something odd in the sample chapter

Reuven M. Lerner on 2002-01-03T04:15:37

Actually, $counter is not incremented -- the program fails to compile or execute, because "use strict" is active and catches a problem before execution can begin. use strict outlaws the use of unqualified global variables, meaning that every variable must be a lexical (declared with my) or a qualified global (with a $full::package::name).

In this sample program, $counter is declared to be lexical for the "foreach" block. So foreach increments $counter once per iteration -- and when the block ends, our lexical $counter disappears from the universe.

So what about $counter in the print statement? Well, the key to understanding this program is that there are really two variables here that (confusingly) have the same name: a lexical $counter that exists within the foreach loop, and a global $counter that is used in the final print statement.

If you were to run this program without use strict, Perl would happily try to do what you have asked for, which is probably not what you want: It would increment the lexical $counter in the foreach loop, and display the (undefined) value of the global $counter in the print statement.

Remember, there is no connection between these two $counter variables; since you haven't assigned a value to the global $counter, it remains undefined through the end of the program.

With use strict in place, the Perl compiler exits with a fatal error, complaining that the global $counter is an unqualified global. When use strict complains about an unqualified global, it's almost always this sort of problem (i.e., referencing a lexical outside of its scope) or a typo in a variable name. In either case, use strict is amazingly helpful.

While there are several ways to solve this problem, the most common is to declare the lexical $counter at the program's top level, outside of (and before) the foreach loop.

With this change, the program has only one variable named $counter (a lexical), whose scope lasts through the end of the file. So use strict is happy, foreach can increment the variable, and $counter is still available at the bottom of the program for printing.

Does this make things clearer?

Re:Something odd in the sample chapter

pudge on 2002-01-03T04:30:09

I think he was referring to the apparently spurious "$counter++;".

Re:Something odd in the sample chapter

Reuven M. Lerner on 2002-01-03T04:55:59

Whoops! The $counter++ is indeed unnecessary, and I'm surprised (er, embarrased?) that neither I nor no one else caught it.

I guess that the errata listing on my site will go up later today...

Re:Something odd in the sample chapter

chromatic on 2002-01-03T05:15:26

Writing books is hard, and proofreading them is worse. If that's the worst error you have, you're lucky. :)

Re:Something odd in the sample chapter

gnat on 2002-01-04T18:14:50

You said it! The people who complain about errata have never written or edited a book. When confronted by them, I can only shrug and say "we got dozens of people to read the book, and none of them found the bug. What else are we supposed to have done?"

--Nat

Re:debugging books

jjohn on 2002-01-05T12:44:38

To amplify what Gnat said, books have no symbolic debugger. They have no compiler. Every thing must be checked by hand, just like in the Golden Age of mainframe computers. This is an extraordinary task even for a simple book. What frequently seems to happen is that the harder bits of code are looked at much more carefully than the seemingly harmless bits. After all, everyone can toss of "hello, world" right?

I've tech reviewed a half dozen books and co-authored one and I'm still amazed at how many things get done *right* rather than the odd things that fall through the cracks. I suppose it's a "half full/half empty" thing.

Thank God for reprints and second editions. :-)

Re:Something odd in the sample chapter

clintp on 2002-01-03T15:04:12

I agree with chromatic: if that's as bad as it gets, be really happy about the text. :)

Small suggestion (if I may). Throughout the earlier parts of the chapter where you're explaining lexical and package variables you've got things like: print "main::x = '$x'\n". You make your point exceedingly well, but I'd be really careful about surrounding variable names with ' marks because they're valid package separators (I didn't see you mention that either) and you might wind up saying something you didn't mean -- especially when typesetting gets a hold of it. Yeah, they're historical, deprecated, etc... but they still cause suffering on occasion.

Re:Something odd in the sample chapter

Reuven M. Lerner on 2002-01-07T12:29:13

You're right that people will occasionally encounter ' as a namespace delimiter instead of ::. But I purposely left out the things that people don't normally use; if you're hacking around in someone's old code that uses $main'foo, then you're probably (hopefully!) smart enough to look through some documentation. A side note wouldn't have been a bad idea, though.

For example, I originally had a section on prototypes in the book. I dumped it because most Perl programmers don't use them on anything approaching a regular basis. Yes, they're useful to some people some of the time -- but so are lots of other things, and you have to draw the line somewhere.

Not to be picky...

belg4mit on 2002-01-03T20:27:07

...but the loop doesn't increment counter.
The loop sets(aliases actually) counter
to succesive elements of the list which is
in this case 1..10 ;-)

Why?

ology on 2002-01-03T22:54:46

Why does the world need yet another introduction to Perl programming?

Re:Why?

pudge on 2002-01-04T01:50:57

We're still trying to get it right!

Re:Why?

ziggy on 2002-01-04T02:00:19

Because the entire world is one big huge audience. :-)

(Actually, it's many audiences; some beginners prefer the existing intro-to-perl books, while others find them lacking)

Read a review of Core Perl

barryp on 2002-02-19T17:36:58

I've written a review of Core Perl which is on the Linux Journal web-site, located here. I had posted news of this to the main board, but for some reason, it never made it as an item ...