duncs has asked for the wisdom of the Perl Monks concerning the following question:

I use Storable (using its lock_xxx methods) to maintain data between a couple of processes, but in one instance I want to amend the data in the stored file.

So, I open the file to get a filehandle, lock it, then use the store_fd and retrieve_fd on the filehandle (to prevent possible race conditions between using lock_store and lock_retrieve from the other processes), but have discovered it doesn't work a I expected. Is this a problem with Storable or my understanding?

Update: Fixed thanks to zwon - was missing a truncate and seek before rewriting the file

#!/usr/bin/perl use strict; use warnings; use Storable qw(retrieve store retrieve_fd store_fd); use Fcntl qw(:flock); my $file='/tmp/storable_test'; my %data = ( item => 'Here I am', ); store(\%data, $file); #===== # open & lock file open(my $fh, '+<', $file); flock($fh, LOCK_EX); # get data, amend, put back my $data = retrieve_fd(\*$fh); print 'item: ', $data->{item},$/; delete($data->{item}); print 'gone (error as expected): ', $data->{item},$/; truncate $fh, 0; # <- *** WAS MISSING THIS *** seek $fh, 0, 0; # <- *** WAS MISSING THIS *** store_fd($data, \*$fh); close($fh); #====== # now reload from the file my $check_data = retrieve($file); print 'why is this here? ', $check_data->{item},$/;

I am guessing its probably my understanding but cannot see why currently.

Thanks

Duncs

Replies are listed 'Best First'.
Re: Storable or user bug?
by zwon (Abbot) on Oct 15, 2009 at 19:49 UTC

    That's because you're adding data to the end of the file. If you don't want to reopen file, just truncate it before invoking store_fd.

    Update: alternatively just use store and it will rewrite file. So use one of these:

    truncate $fh, 0; seek $fh, 0, 0; store_fd($data, \*$fh); close($fh);
    or
    store($data, $file); close $fh;

      Thanks got it - thanks.

      I had tried the truncate, but that didn't work as expected as I didn't also do the seek...

      Duncs

Re: Storable or user bug?
by Khen1950fx (Canon) on Oct 15, 2009 at 21:18 UTC
    I tried it like this:

    #!/usr/bin/perl use strict; use warnings; use Storable qw(retrieve store retrieve_fd store_fd); use Fcntl qw( :flock ); my $file = '/tmp/storable_test'; my (%data) = ( item => 'Here I am' ); store(\%data, $file ); open my $fh, '+<', $file; flock $fh, LOCK_EX(); my $data = retrieve_fd( \*$fh ); print 'item: ', $data->{'item'}, $/; delete $data{'item'}; print 'gone (error as expected): ', $$data{'item'}, $/; store_fd( $data, \*$fh ); close $fh; my $check_data = retrieve($file); print 'why is this here? ', $$check_data{'item'}, $/;

    It returned this:

    item: Here I am gone (error as expected): Here I am why is this here? Here I am