logo       

Re: [SPOILER] Perl 'Easy' Quiz of the Week #2005-1: msg#00046

lang.perl.qotw.discuss

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

On Mon, Jan 24, 2005 at 01:11:33PM -0500, Daniel Martin wrote:
> 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.

Unfortunately, you've missed the other special case
where pre.M exists in the input - your code would
generate a second copy of that line.

I'd change:

if ($mline lt $_) {
print $mline;
$mline = '';
}

to:

print $mline if $mline lt $_;
$mline = '' if $mline le $_;

--



<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

News | FAQ | advertise