Just a simple [cpan.org] guy, hacking Perl for fun and profit since way back in the last millenium. You may find me hanging around in the monestary [perlmonks.org].
What am I working on right now? Probably the Sprog project [sourceforge.net].
GnuPG key Fingerprint:
6CA8 2022 5006 70E9 2D66
AE3F 1AF1 A20A 4CC0 0851
I have a replication process which applies updates. Usually the updates are incremental 'patches' sometimes they are full copies. The incoming queue of updates might look like this:
my @files = qw(
00000.diff
00001.diff
00002.diff
00003.copy
00004.diff
00005.diff
00006.copy
00007.diff
);
If there are one or more full copies in the queue, there is no point processing any updates before the last full copy. So what I needed was an algorithm to reduce the above example to just the last two files.
My first thought was that I ought to be able to do it with some form of grep using the flip-flop operator. Alas, my initial attempts were not successful so I wrote a loop that popped things off one array and unshifted them onto another - breaking out of the loop if a full copy file was found. It wasn't complicated code but it took more lines than I'd have liked and it needed a one-line comment explaining what the loop was doing (perhaps, in retrospect, I should have put it into a subroutine).
I later realised what I was doing wrong in my first attempts and came up with this version:
my $i = 0;
@files = reverse grep !$i++../\.copy$/, reverse @files;
Having to use $i was annoying but I couldn't think of another way to code an expression that was true the first time it was evaluated and false from then on.
Anyway, I ran this version past a couple of my colleagues and while they were intrigued, they felt it was basically unreadable and didn't want to be saddled with maintaining it. So I 'committed' it here instead
My shot (Score:2)
Re:My shot (Score:2)
before_incl (Score:1)
Perhaps try the List::MoreUtils module?
Unreadable Perl Code (Score:1)
...So what I needed was an algorithm to reduce the above example to just the last two files....
Or, at least, you want to get the last index of a /\.copy$/ match from the list.
List::Util improves this (Score:1)
No need for the flip-flop (Score:1)
The double
reverseis still unsightly though.There's no fold in List::Util or List::MoreUtils (Score:1)
Anyway, here's a fold-using implementation:
use strict;
sub fold {
my $accum = shift;
my $code = shift;
return $accum unless @_;
return fold( $code->( $accum, shift ), $code, @_ );
}
my @files = qw(
00000.diff
00001.diff
00002.diff
00003.copy