I started programming perl again as the codebase at Overseas Family School has java and perl. Which draws me back to usability in perl, and so now I'm updating some of my old habits to kindler, gentler methods of code delivery to your brain.

Regular expressions can become illegible in a hurry, I used to deal with this by breaking the regexps into smaller regexps and hiding them indented below the relevant line:

 
	$re = qr/^($ip) ($host) ($msg)$/ if (
		$ip = qr/\d+\.\d+\.\d+\.\d+/,
		$host = qr/[\_\.\-\w]+/,
		$msg = qr/.*/
	);
	'4.2.2.2 my_host printer (lp1) is on fire!!!' =~ $re and return $3,$2,$1;
Since Modern::Perl means using strict, the above won't fly anymore, and so I use the following which accomplishes the same indent-hiding, however we've now vertically separated the variable declaration for $re from the value as we understand it on the screen :
 
	my $re = eval {
		my $ip = qr/\d+\.\d+\.\d+\.\d+/;
		my $host = qr/[\_\.\-\w]+/;
		my $msg = qr/.*/;

		return qr/^($ip) ($host) ($msg)$/;
	};
	'4.2.2.2 my_host printer (lp1) is on fire!!!' =~ $re and return $3,$2,$1;

I'm not psyched. Any ideas for improvement?


Perl regexp are hard to do a good job of commenting. I just put a note with it that says what it's doing and hope any future updater will know enough to decipher it. Yesterday, I discovered some of the Regexp::Common modules on Perl and they're a nice time saver to avoid recoding the wheel. - Cal

Actually, I break the regexps down for my own benefit, as solving a series of simple problems appears to cost much less than solving them simultaneously, since I get less headaches when I code this way. ;) -- Patrick

Just back from YAPC where I got to hear about lots of this ;-) You don't need to escape all those characters in the character class -- regexes are hard enough to read ;-) (but the - needs to be first or last) Since it sounds like you're using Perl 5.10, it supports some nifty new things, including named capture buffers. What about something like this: use 5.10.0; my $msg = '4.2.2.2 my_host printer (lp1) is on fire!!!'; $msg =~ / (?\d+\.\d+\.\d+\.\d+) # IP address (?\s[-\w.]+) # System hostname (?.*) # Description of error /x; say "$+{ip} $+{host} $+{description}"; When using the named capture stuff, the matches are available in the %+ hash. -Eric

Hrm, your blog snarfed my code :-) Here's a link to pastie with the above mentioned Perl code in it: http://pastie.org/526453 -Eric

Ok, <> pasting should work here now