SPUG:Use of (?{}) in a subroutine gives off weirdness with $^N
Chris Wilkes
cwilkes-spug at ladro.com
Wed Jan 29 02:30:04 CST 2003
I thought I would try out the (?{}) construct to see how it works, and
for the most part it is working except when I put it in a subroutine.
The following code works:
-----------------------------------------------
#!/usr/bin/perl -w
use strict;
my $amt;
$_ = "you owe me 100";
/
\s+ # start of whitespace
(\d+) (?{ $amt = $^N })
\s*$ # anything afterwards
/x;
print "$amt,$_\n";
$_ = "bank owes me 200";
/
\s+ # start of whitespace
(\d+) (?{ $amt = $^N })
\s*$ # anything afterwards
/x;
print "$amt,$_\n";
-----------------------------------------------
But if I do the (?{}) in a subroutine the $amt variable is lost the 2nd
time around, even though it should get the $^N value:
-----------------------------------------------
#!/usr/bin/perl -w
use strict;
my ($line, $amt);
$line = "you owe me 100";
$amt = modline($line);
print "$amt,$line\n";
$line = "bank owes me 200";
$amt = modline($line);
print "$amt,$line\n";
sub modline {
my $tmpline = shift;
my $tmpamt;
$tmpline =~
/
\s+ # start of whitespace
(\d+) (?{ $tmpamt = $^N ; print "found '$tmpamt'\n"; })
\s*$ # anything afterwards
/x;
return $tmpamt;
}
-----------------------------------------------
What gives? I threw in the print statement in the sub to see if the
pattern is matching and it does. You can take it out and look at the
$^R value after the regex and see that it contains the digit matched (if
you leave in the print $^R is set to 1, the return code of print).
Looking through the perlre perldoc I suspect it has something to do with
this:
The code is properly scoped in the following sense: If the assertion
is backtracked (compare the section on Backtracking), all changes
introduced after localization are undone,
but what I can't understand is that if the match worked the first time
through, why not the second?
Am I using (${}) in a bad way?
Chris
More information about the spug-list
mailing list