Regex classes under Unicode

This week in The Effective Perler, I posted about the oddness of character classes. In Know your character classes under different semantics”, I showed that the trusty character class shortcuts \w, \w, and \s that we know from the first edition aren’t the same thing now. In fact, they haven’t been the same thing since the fourth edition. As I’ve said before, we have basically ignored Unicode despite its support since Perl 5.6. Now we’re paying the Unicode tax; I just have to integrate this into the Learning Perl.

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).

Updates to chapter 17, “Advanced Topics”

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

Chapter 17 of Learning Perl is a catch-all chapter at the end of the book. We cover some “advanced” items to pique the interest of the reader and to segue into Intermediate Perl. Mostly, this covers grep, map, and eval.

Since we also cover Perl modules, we expanded this chapter a bit. The list operators are nice, and since list operations are most of many programs, so we should at least mention List::Util and List::MoreUtils.

The eval is the minimum for dealing with errors, and it also provides quite a bit of trouble as it handles $@. So, we also introduce Try::Tiny. We don’t say much about it, but anyone who makes it this far at least finds out that it exists. While we are at it, we might as well throw in autodie, especially since it’s part of the Standard Library.