# used by munge function to safely interpolate
# $1, $2 etc into the replacement string
sub _safeswitch {
my @P = (undef,$1,$2,$3,$4,$5,$6,$7,$8,$9);
$_[0] =~ s/\$(\d)/$P[$1]/g;
$_[0];
}
If I read the above correctly, it'll only handle 9 sets of
capturing parens, and it's possible that we may have matched more than 9 sets.
My fix is to dynamically build @P to size.
# used by munge function to safely interpolate
# $1, $2, etc. into the replacement string
sub _safeswitch {
my %seen;
@seen{@+} = (undef) x @+;
my @P;
{
no strict 'refs'; # allow $$_ to be $1, $2, etc.
no warnings 'unitialized'; # allow undef as $$_
@P = map { $$_ } undef, 1 .. scalar keys %seen;
}
$_[0] =~ s/\$(\d+)/$P[$1]/g;
$_[0];
}
And a test:
#!/usr/bin/perl
use strict;
use warnings;
my $str = 'abcdefghijklmnopqrstuvwxyz';
my $pat = '(.).(.).(.)..(.).(.)(.)(.).(.)(.)(.).(.)(.)(.)(.).+';
my $repl = '$5$14$12$13 $1$8$9$13$4$3$11 $10$3$11$7 $4$1$2$6$3$11';
print munge( $str, $pat, $repl ), "\n";
sub munge {
my($str, $pat, $repl) = @_;
$str =~ s/$pat/_safeswitch($repl)/eg;
return $str;
}
# used by munge function to safely interpolate
# $1, $2, etc. into the replacement string
sub _safeswitch {
my %seen;
@seen{@+} = (undef) x @+;
my @P;
{
no strict 'refs'; # allow $$_ to be $1, $2, etc.
no warnings 'uninitialized'; # allow undef as $$_
@P = map { $$_ } undef, 1 .. scalar keys %seen;
}
$_[0] =~ s/\$(\d+)/$P[$1]/g;
$_[0];
}
exit;
UPDATE
- my %seen
- no warnings 'unitialized';
- allow multiple digits in s/// in _safeswitch
- add test case
Incidentally, the line @seen{@+} = (undef) x @+; is a faster way to build
such a hash than the various equivalents ( %seen = map { $_ => undef } @+;
most notable among them for being popular and 4x slower).
I discovered this just today ;)
blyman
setenv EXINIT 'set noai ts=2' |