Well, i hope it's not bad form to answer your own question...
Two (so far) very good replies, but in the meantime i found something even easier|better, i think.
This node is the one i was looking for, and it's all about Tie::File, which essentially turns any flat-file into an array manipulable with Perl in the usual fashion. Absolutely perfect for what i needed.
Here's a stripped-down version of the code i ended up generating:
tie @log, 'Tie::File', $logfile or displayError("could not open logfil
+e");
while ($some_condition) {
#do some other stuff, and
unshift @log, $info_to_be_logged;
}
# find out how long the logfile is, and truncate it
$length = @log;
$truncate = $length - 150;
if ($truncate > 0) {
$#log -= $truncate;
}
untie @log;
By using unshift, each new entry is made at the beginning of the array/file. By truncating the array/file at a fixed number of records before closing, the file essentially becomes FIFO. Of course this isn't perfect, the logfile can swell up a lot while in use, before it gets truncated and there isn't any locking (unless it's built into Tie::File, it seems to be one mightily sophisticated module), but i'm not too concerned.
For the curious, here's a copy of the actual sub that it's used in.... yes, this is my 'production' code, and i know it's pretty horrible ;-)
sub delete_threads_from_file
{
$logfile = "$htdocs${bbs_location}/$removed_log";
tie @log, 'Tie::File', $logfile or displayError("could not open lo
+gfile");
local($file, $delete_hash) = @_;
local(*FILE);
local($new_content);
if ((open(FILE, "$file"))) {
while($line = <FILE>) {
if ($line =~ /<!-- mid="(.*?)" -->/) {
local($id) = ($line =~ /<!-- mid="(.*?)" -->/)[0];
$should_delete = 0;
foreach $delete_id (keys(%{$delete_hash})) {
# look for exact id matches
if ($id eq $delete_id) {
$should_delete = 1;
# add this id to the removed.log
unshift @log, $delete_id;
}
# if the delete_id(message) is a topic message,
# remove all its responses
local($d_thread_id,$d_message_id) = split(/_/, $de
+lete_id);
local($thread_id,$message_id) = split(/_/, $id);
if (($d_thread_id == $d_message_id)&&($thread_id =
+= $d_thread_id)) {
$should_delete = 1;
# if this is a response to a removed topic,
# add it to the removed.log
if ($id ne $delete_id) {
$should_delete = 1;
unshift @log, $id;
}
}
}
if (! $should_delete) {
# this id is NOT in our list of ids to delete, so
+keep it
$new_content .= $line;
}
}
else {
$new_content .= $line;
}
}
close(FILE);
# find out how long the logfile is, and truncate it
$length = @log;
$truncate = $length - 150;
if ($truncate > 0) {
$#log -= $truncate;
}
untie @log;
}
###
### modify the file
###
if ((open(FILE, "> $file"))) {
print FILE $new_content;
close(FILE);
}
}
|