Updates to Chapter 13, “Directory Operations”

[This post notes differences between the fifth and sixth editions.]

Our updates to Chapter 13 aren’t that exciting. There’s not much that has changed in the world of Perl and directories. It’s almost dull, even.

  • Use variables as directory handles: opendir my $dir, $directory.
  • Mention a couple more modules incidental to some of the examples, including File::Spec::Functions, Path::Class, and File::Temp
  • Show a find2perl example. We mentioned File::Find only to say that we weren’t going to say anything about it. Also mention the improved interfaces of File::Finder and File::Find::Rule

Updates to Chapter 7, “In the World of Regular Expressions”

[This post notes differences between the fifth and sixth editions.]

I just committed the new Chapter 7, “In the World of Regular Expressions”. It was quite an education, even for me, because the character class stuff has changed so much since Perl 5.6, and, since Learning Perl had been ignoring Unicode, we didn’t face the hard problems.

  • The \w character class is almost dangerous now. By default, it represents over 100,000 characters that can match at that position. The \d and \s character classes have the same problem on a smaller scale. It’s unlikely that anyone actually wants these shortcuts anymore, but there are still in older programs. I did cover this over at The Effective Perler, too.
  • Since we’re covering Unicode, this is the right chapter to cover the Unicode properties, such as \p{Space}. Those don’t completely solve the character class shortcut problem because they still match many characters. The perluniprops documentation lists how many characters match each property, which is kinda cool.
  • Perl 5.13.9 includes Karl Williamson’s work to add the /a adverb to enforce ASCII semantics, so we use that
    too even though we don’t really get into options into the next chapter.

This is all rather painful to update because I didn’t want to go through everything assuming ASCII semantics (so, very few changes) then tack on an “if you are using Unicode” section that then invalidates everything. We just have to bite the bullet and make the switch to thinking of Unicode as the default and ASCII as the backward-compatibility special case.

Updates to Chapter 12, “File Test Operators”

[This post notes differences between the fifth and sixth editions.]

This chapter probably doesn’t deserve an update here because almost nothing changed. Most of the updates is just make all the code examples consistent. When I added the Perl 5.10 updates for the stacked file test operators, I used a style that wasn’t quite my own, but not quite the one Tom and Randal had already used in the book. It’s more jarring in this chapter than in Chapter 15 (“Smart matching”), a completely new chapter in the fifth edition, because you can see two different styles on the same page. And, I’ve updated Chapter 15 too.

There is one area where I can use some feedback though. We say:

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.

However, we don’t give any suggestions for what a good book might be. What would you choose?

when(), Try::Tiny, and autodie

I’m working on Chapter 17, which is the catch-all chapter for topics we think that segue into the other books in the Learning Perl series. Although Mastering Perl has an entire chapter on catching and reporting errors, we want to at least survey the topic in Learning Perl.

The first edition of Learning Perl noted that eval existed and gave a couple of examples, and in each subsequent edition the discussion became more involved.

Starting with the fourth edition, we devoted a chapter to using Perl modules, acknowledging the fact that Perl’s greatest feature is CPAN. In that edition, it was fairly late in the book. In the fifth edition, we moved that chapter toward the middle of the book. In each case, this means that we can then use Perl modules, whether from the Standard Library or CPAN, for the rest of the book since we’ve covered the idea of using modules. Our goal is always to cover any topic before we use it.

Since the sixth edition also covers modules, we can use it when we talk about catching errors. That means that we can talk about autodie, the pragma that became part of the Perl core in 5.10.1, and Try::Tiny, which is not a core module. We might have covered autodie in the fifth edition, but we only covered up to Perl 5.10.0. Paul Fenwick just barely missed the cut-off.

So, while working on the eval section, I was playing with some examples. I covered eval, Try::Tiny, and autodie separately, but I was wondering what would happen if I combined them. Could try and autodie cooperate?

I started with the example from the autodie documentation:

eval {
   use autodie;
   open(my $fh, '<', $some_file);
   my @records = <$fh>;
   # Do things with @records...
   close($fh);
};

given ($@) {
   when (undef)   { say "No error";                    }
   when ('open')  { say "Error from open";             }
   when (':io')   { say "Non-open, IO error.";         }
   when (':all')  { say "All other autodie errors."    }
   default        { say "Not an autodie error at all." }
}

Then I added Try::Tiny and started playing around with it:

use 5.010;

use autodie;
use Try::Tiny;

my $filename = '/does/not/exist';
try {
  open my $fh, '>', $filename; # still dies on error
  }
catch {
  when( 'open'  ) { say 'Got an open error'; continue; }
  when( 'close' ) { say 'Got an open error'; continue; }
  when( ':io'   ) { say 'Got an io error';   continue; }
  };

The output is not what I expected. It does what it looks like it should do:

Got an open error
Got an io error

I was surprised that this worked, and that it worked without a warning. That when is outside an official topicalizer (something that sets $_, such as given or foreach ).

That’s one of the interesting parts of writing a book. To properly research something, we think about the different ways we might combine things and especially how things might break. When we’re teaching, we’re going to run into all sorts of crazy syntheses of the topics. With a bit of experience, we can anticipate some of that, and when we do we discover some interesting things like this.

Updates to Chapter 16, “Process Management”

[This post notes differences between the fifth and sixth editions.]

“Process Management” has been one of our neglected chapters for updates, being much the same in the fifth edition as it was in the third. It’s at the end of the book and it doesn’t immediately assert itself as a chapter needing work like a chapter on regular expressions does. We don’t often think about new features in interprocess communication, at least until now.

We didn’t really have to change anything big, but there are a lot of additional examples for signals and piped opens. A lot has happened in those areas since we last added to this chapter.

In the fifth edition, we had a lot of words to warn about “unsafe signals”. Way back in Perl 5.7.3 (yes, before the fourth edition!), Perl moved to deferred signals. And, although the fourth edition covers Perl 5.8, that really means that a lot of people were still using Perl 5.005 so we still needed the warning. I bet most people had moved to Perl 5.6 by the time the fifth edition came out. But, now that it’s 2011, we’re going to assume that life started with Perl 5.8. If people are using something before then, they are out of luck with the new edition.

You can read about signals in the perlipc documentation. Instead of interrupting the program, which might be in the middle of a system call, allocating memory, or something else that needs to finish so things don’t go horribly wrong, perl lets them finish. For most signals, perl merely sets a flag and keeps doing what it was doing. When perl gets to a safe spot, like the space between opcodes, it checks for the signal flags and handles what it finds.

For the pipes, it’s time to move those to the three (or more) argument form of open. Previously we had this example:

open DATE, "date|" or die ...;

With the three-argument open:

open my $date_fh, '-|', 'date' or die ...;

Note that autodie doesn’t show up until the next chapter, so we still use die.

And, since we emphasize modules much more in this edition, we added a short introduction to IPC::System::Simple, even though it’s not a core module (yet).