I have a bunch of scripts that process several batches of “things”, whatever those may be, where each batch may or may not contain processible “things”. F.ex, that might be a list of directories of which each may or may not contain files to process, or an email folder full of messages that may have one or more files attached (see attachments — mass-dumps file attachments from mail), or such.
Usually, I want progress indication in the form of
dir1: file2, file8, file9
dir3: file6
dir4: file1, file2, file3
The following snippet contains a function generator that does the job. Use it as in:
for( 1 .. 10 ) {
my $print = make_printer( "dir$_" );
next if 0.3 > rand;
for( 1 .. 10 ) {
next if 0.3 > rand;
$print->( "file$_" );
}
}
If you are processing batches with very large items, don't forget to unbuffer the output handle so you see the intermediate updates immediately.
sub make_printer {
my $hdr = shift;
my $count;
return bless sub {
my $item = shift || do {
print "\n" if $count;
return;
};
print( ( $count ? "," : "$hdr:") , " ", $item );
++$count;
}, 'PRINTER';
sub PRINTER::DESTROY { shift->() }
}