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

I have a set of objects that I am using Storable with to thaw and pass over a network to be unthawed and used. Occasionally, one of these objects will contain a cached database handle that gets serialized with the rest of the data. When this is subsequently thawed and eventually destroyed on the remote end, I get all sorts of nasty DBI errors about how the RV is not "magic" and does not refer to a valid database handle. The database handle will not be used on the remote end (naturally).

My thought then was to take advantage of the Storable hooks, and simply write one for DBI::db that passed back a string "Lost DBI ref $ref" along the same lines that setting $Storable::forgive_me allows a simple "lost data" string to appear in place of file handles or other un-storable data. This is how I approached it:

sub DBI::db::STORABLE_freeze { my ($self, $cloning) = @_; return if $cloning; return "Lost DBI ref $self"; }
When executing with this subroutine in place, however, I get this error message:
Unexpected object type (4) in store_hook() at blib/lib/Storable.pm (autosplit into blib/lib/auto/Storable/_freeze.al) line 234, at script-name.pl line 58
Both this error message and store_hook() itself appear to be in the .so for Storable, not in any of the Perl code, so short of downloading the source (which is my next logical step, after this), it's difficult to see what it's talking about. The documentation only mentions that hooks need to return a "serialized version" of the object being passed. I have also tried returning other things:
return freeze("string"); # probably 'cause it's not a ref my $$msg = "string"; return freeze($msg); # still no-go
I'm guessing the "serialized version" needs to be a little more "serialized" than this, but how do I need to go about doing this?

Replies are listed 'Best First'.
Re: Avoiding DBI handles with Storable
by runrig (Abbot) on Jan 31, 2001 at 05:00 UTC
    I still don't get what the return value of the STORABLE_freeze function does to anything (other than returning an empty list to nullify the subroutine, I can't get the return value to do anything; maybe its broken?), but I've been messing with freeze/thaw hooks and here's what I have which may help (Maybe the secret is to just thaw it the way you want?):
    #!/usr/local/bin/perl -l -w use strict; use Storable; use Data::Dumper; package MyPack; sub new { my $class = shift; bless {attrib=>"red"}, $class; } sub STORABLE_freeze { my ($self, $cloning) = @_; return if $cloning; return $self; } # $self always seems to be an empty object # blessed into the class, so lets re-bless it. sub STORABLE_thaw { my ($self, $cloning) = @_; return if $cloning; bless $self, 'NoPackage'; $self->{mykey} = "value"; return $self; } package main; my $obj = MyPack->new; my $thing = { a=>"abc", b=>$obj }; print Dumper($thing); store $thing, 'store.tmp'; my $another_thing = retrieve('store.tmp'); print Dumper($another_thing); Output: $VAR1 = { 'a' => 'abc', 'b' => bless( { 'attrib' => 'red' }, 'MyPack' ) }; $VAR1 = { 'a' => 'abc', 'b' => bless( { 'mykey' => 'value' }, 'NoPackage' ) };
      When Storable comes across a reference blessed into a class, it examines that class to see if there is a 'STORABLE_freeze' method (and _thaw, I guess, but that's out of the scope of this question) that can produce a "serialized" version of that object. If it exists, according to the documentation for Storable, it's to return a serialized version of the object. If no such method exists (or if the first invocation of this method returns an empty list), Storable reverts to what it normally does.

      I am just attempting to define a STORABLE_freeze method for the DBI database handle (which seems to be of the DBI::db class, but I haven't been able to investigate past this point yet), which returns a garbage/no-op serialization for the database handle, much like what Storable does by default when you set $Storable::forgive_me and attempt to serialize a coderef or a file handle. Make sense?

      Your code seems to work as-is, though, without error (though your _thaw routine is non-sensical from a Storable point of view, as it does nothing to restore the value that was saved, but that doesn't matter), so I'm wondering if I'm doing something wrong at a more fundamental level...

Re: Avoiding DBI handles with Storable
by Fastolfe (Vicar) on Feb 07, 2001 at 04:46 UTC
    It turns out this was due to a bug in Storable. It seems it does not play well with tied blessed references. It is being addressed by the author. Thanks anyways.