[SPOILER] Perl 'Easy' Quiz of the Week #2005-1

Daniel Martin <martin-+m399P62/[email protected]> Mon, 24 Jan 2005 13:11:33 -0500 (EST)
Newsgroups gmane.comp.lang.perl.qotw.discuss
Message-ID <[email protected]>
Huh.  No one so far seems to have hit upon the solution I hit upon, which 
was:  (I've deliberately left out most error checking since I want the 
main script body uncluttered)

#!/usr/bin/perl
use strict;

open(STDIN, '<', shift) if @ARGV;
open(STDOUT, '>', shift) if @ARGV;

my $mline='';
my $prefix='';

while(<>) {
   /^(\w+)\.[A-Z]$/ or die "Bad line: $_";
   if ($prefix ne $1) {
     $prefix = $1;
     print $mline;
     $mline = "$prefix.M\n";
   }
   if ($mline lt $_) {
     print $mline;
     $mline = '';
   }
   print;
}
print $mline;
__END__


If I were into justifying my code with grand principles, I'd point out 
that this is an example of the "null object" pattern 
(http://c2.com/cgi/wiki?NullObject) - I end up doing {print $mline} often, 
but when $mline is the empty string, this print statement has no effect. 
Therefore I don't need several extra variables to track whether I've 
already printed the proper thing or not, or whether I'm dealing with the 
first line of the file, etc.  I dislike special cases, because I always 
get into 1-off errors when dealing with them.  Using {print ''} as a no-op 
allows me to do away with special cases.