Updates to Chapter 15, “Smart matching and given-when”

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

We published Learning Perl, 5th Edition in 2008, meaning that we were writing it toward the end of 2007. Perl 5.10 had just come out after being years in development. We just had a peek at the final features as the book was going to press, so the 5th Edition covers Perl 5.10.0. That point release is important, because Perl 5.10.1 changed the smart match in one significant way; it’s now not commutative. We covered smart matching and the new given-when in Chapter 15, which we need to slightly update.

As people started to use Perl 5.10, they realized there were many problems with the new smart match operator, ~~. The smart match looks at its operands and then does something special based an what it sees. It doesn’t have to do the same sort of task for every set of operands. For instance,

$fred ~~ $barney;  # $fred eq $barney

In Perl 5.10.0, perl didn’t care which side the operands were on. The smart match was supposed to be commutative, meaning that $n ~~ $m should be the same as $m ~~ $n, where the operands are flipped around. That doesn’t quite work out because the smart match is a little too dumb about strings and numbers, so these were the same thing because the order of the operands doesn’t matter:

if( 1 ~~ '1one' ) { ... }
if( '1one' ~~ 1 ) { ... }

Both of those are false in Perl 5.10.0 because each does a string comparison, even though one of them is a number that perl must convert to a string. That means that you couldn’t use a smart match if you wanted a numeric comparison. This is important because the when in uses $_ as the lefthand side of the implicit smart match and you specify the righthand operand:

given( $number ) {
    when( 4 ) { ... }
    }

Since you put a number there, you’d think that you’d get a numeric comparison, but you don’t. That’s a problem. Since Perl 5.10.1, the order of the operands matter, and you basically have to consult the table in perlsyn‘s section on the “Switch statement”.

This change doesn’t affect too much of the text in Chapter 15 because we shied away from some of the more complex examples. Our code still works, and we hope that people will skip over Perl 5.10 to at least Perl 5.12, but we never know. We’ll still have to add some warnings about that particular release of Perl.