[sf-perl] A bit of an eye opener with capture variables

David Alban extasia at extasia.org
Thu Aug 3 13:11:24 PDT 2006


I'm reading Perl Best Practices and came across (p.253):

  Pattern matches that fail never assign anything to $1, $2, etc., NOR
  DO THEY LEAVE THOSE VARIABLES UNDEFINED.

  [emphasis mine]

I've always thought that anything that didn't get matched was made to
be undef.  I was very surprised to learn otherwise:

  #!/usr/bin/perl

  use warnings;
  use strict;

  my $strings = [
                  "d e f",
                  "b c",
                  "a",
                ];

  for my $s ( @$strings ) {
    print qq{'$s'\n};

    $s =~ m{ \A \s* ( \S+ ) \s* ( \S+ ) \s* ( \S+ ) }xms;
    my ( $a, $b, $c ) = ( $1, $2, $3 );

    print "         a => ", defined $a ? "<$a>" : "UNDEF", "\n";
    print "         b => ", defined $b ? "<$b>" : "UNDEF", "\n";
    print "         c => ", defined $c ? "<$c>" : "UNDEF", "\n";
  } # for

This prints:

'd e f'
         a => <d>
         b => <e>
         c => <f>
'b c'
         a => <d>
         b => <e>
         c => UNDEF
'a'
         a => <d>
         b => <e>
         c => UNDEF

Yikes!

The book goes on to explain this by saying that if a match fails, a
capture variable "may have been set by some earlier successful match
in the same scope".

So I tried changing the scope in which the match is done:

  for my $s ( @$strings ) {
    print "'$s'\n";

    my ( $a, $b, $c );

    do {
         $s =~ m{ \A \s* ( \S+ ) \s* ( \S+ ) \s* ( \S+ ) }xms;
         ( $a, $b, $c ) = ( $1, $2, $3 );
    };

    print "         a => ", defined $a ? "<$a>" : "UNDEF", "\n";
    print "         b => ", defined $b ? "<$b>" : "UNDEF", "\n";
    print "         c => ", defined $c ? "<$c>" : "UNDEF", "\n";
  } # for

and got the results I had previously (erroneously) expected:

'd e f'
         a => <d>
         b => <e>
         c => <f>
'b c'
         a => UNDEF
         b => UNDEF
         c => UNDEF
'a'
         a => UNDEF
         b => UNDEF
         c => UNDEF

Like I say, a bit of an eye opener.

David
-- 
Live in a world of your own, but always welcome visitors.


More information about the SanFrancisco-pm mailing list