Subject: | SWIG and Storable, STORABLE_attach |
Date: | Tue, 30 Dec 2008 15:42:25 +0100 |
To: | bug-Storable [...] rt.cpan.org |
From: | Thomas Handorf <ThomasHandorf [...] web.de> |
Hi,
there seems to be a problem with STORABLE_attach: If the class
implementing STORABLE_attach is a tied hash, Storable fails, if more
data is stored in the frozen string.
This is important for SWIG proxy classes, as they are represented by a
tied hash.
An inspection of the sources of Storable shows that the magic object of
the tied hash is not retrieved after calling STORABLE_attach. Hence it
remains in the string and is messing up the remainder of the retrival
process.
Possible solutions would be to just croak (maybe not satisfying), to
retrieve the magic and dispose it as STORABLE_attach may deal with the
object creation alone, or to continue with the creation of the magic
object just as in case of STORABLE_thaw.
Unfortunately I don't know how to do that (for solution 2 and 3), that's
why I can't provide a patch here.
For the time being, SWIG proxy classes can be stored with the following
routines (assuming that $self->tos returns a string representation of
the c-object and the constructor ($pkg->new()) can take such a string to
intialize a new object)
# support for storing and retrieving via Storable
# Note: the hooks get called twice, once for the tied hash and once for
the actual object pointing to the c-object
# Warning: this implementation strongly depends on the current
implementation and data layout of the swig proxy classes.
# If this is changed in future swig releases this may break!!!
sub STORABLE_freeze{
my ($self, $cloning) = @_;
if ($self->isa('HASH')){ # just the tied hash, ignore
return "";
}
# here we got the actual object.
my $str=$self->tos(); # get string representation
return $str;
}
sub STORABLE_thaw{
my $self=shift;
my $cloning=shift;
my $str=shift; # the serialized object
if ($self->isa('HASH')){ # just the tied hash
return;
}
# here we thaw the actual object
my $pkg=ref($self); # package name
# get a new object using the serialized data. This already is a tied
hash
my $newself=$pkg->new($str);
my $newobj=tied %$newself;# get the actual object of the new object
#copy the pointer to the new c-object to $$self, i.e. without
modifying $self. Storable wants the initialized object at the reference
it already created for it, namely $self
$$self=$$newobj;
# disown the c-object, thus the c-object, which is already copied to
$self, is not deleted if $newself goes out of scope
$newself->DISOWN();
# set ownership for $self, thus if the retrieved object is destroyed
also the c-object gets destroyed.
# cannot use AQUIRE here as this expects the tied hash and not the
object
my $own="${pkg}::OWNER";
${$own}{$self}=1;
}
Cheers, Thomas
Versions:
Perl: v5.8.8 built for i586-linux-thread-multi
Storable: 2.18
SWIG: 1.3.29