Well... Perl is not evil, but there is some Perl that can cause some unusual behaviour.

What perl is Evil?

  • $&
  • $'
  • $`

What is the downside of using them

Performance... well lack of. For large regular expressions.

my $count = 0;
while (1) {
        $count++;
        if ($text =~ /\G([^<]+)/gcs) {
        } elsif ($text =~ /\G<!--(.*?)-->gcs) {
        } elsif ($text =~ /\G<\?xml(.*?)\?>gcs) {
        } elsif ($text =~ /\G<\?(.*?)\?>gcs) {
        } elsif ($text =~ /\G<(.*?)(\/)?>gcs) {
        } else {
                last;
        }
}

Quick Perofrmance Test

$ time perl test.pl 
Fake loop start - size 488606
Fake loop end - for 21583

real	0m0.073s
user	0m0.068s
sys	0m0.005s

$ time perl test.pl  evil
Fake loop start - size 488606
Fake loop end - for 21583

real	0m12.830s
user	0m5.558s
sys	0m7.266s

Quick Perofrmance Test

175 times slower

Alternatives

e.g. To get the end of the string not matched

	# OLD
	$test =~ /OSDC2007/;
	$rest = $&;

	# NEW
	$test =~ /OSDC2007(.*)$/;
	$rest = $1;

It's not all good news

Using brackets to capture...

  • The Good
    • Does not slow down other Regular Expressions
  • The Bad
    • Using captures like above are actually slower
    • For that one expression !

So use it ?

  • Use it by all means
  • But never in a library - especially one for CPAN
  • And think about them - they may be fast for one - but what about the whole application?

Testing Code

  • use Devel::SawAmpersand - Test it after loading modules
  • use Devel::FindAmpersand - does not work if perl has been compiled with threads (most perl !!!)
  • Performance test your code

Modules effected

There are bound to be more...

  • Text::Balanced - although the latest has been fixed
  • Note: Lots of moudles use Text:Balanced...
  • XML::XPath - try using XML::LibXML instead
  • XML::ESISParser, Parse::RecDescent, Spreadsheet::ParseExcel::Utility

Talk History