3 # BioPerl module for Bio::Root::Storable
5 # Please direct questions and support issues to <bioperl-l@bioperl.org>
7 # Cared for by Will Spooner <whs@sanger.ac.uk>
9 # Copyright Will Spooner <whs@sanger.ac.uk>
11 # You may distribute this module under the same terms as perl itself
13 # POD documentation - main docs before the code
17 Bio::Root::Storable - object serialisation methods
21 my $storable = Bio::Root::Storable->new();
23 # Store/retrieve using class retriever
24 my $token = $storable->store();
25 my $storable2 = Bio::Root::Storable->retrieve( $token );
27 # Store/retrieve using object retriever
28 my $storable2 = $storable->new_retrievable();
29 $storable2->retrieve();
34 Generic module that allows objects to be safely stored/retrieved from
35 disk. Can be inhereted by any BioPerl object. As it will not usually
36 be the first class in the inheretence list, _initialise_storable()
37 should be called during object instantiation.
39 Object storage is recursive; If the object being stored contains other
40 storable objects, these will be stored seperately, and replaced by a
41 skeleton object in the parent heirarchy. When the parent is later
42 retrieved, its children remain in the skeleton state until explicitly
43 retrieved by the parent. This lazy-retrieve approach has obvious
44 memory efficiency benefits for certain applications.
47 By default, objects are stored in binary format (using the Perl
48 Storable module). Earlier versions of Perl5 do not include Storable as
49 a core module. If this is the case, ASCII object storage (using the
50 Perl Data::Dumper module) is used instead.
52 ASCII storage can be enabled by default by setting the value of
53 $Bio::Root::Storable::BINARY to false.
61 User feedback is an integral part of the evolution of this and other
62 Bioperl modules. Send your comments and suggestions preferably to one
63 of the Bioperl mailing lists. Your participation is much appreciated.
65 bioperl-l@bio.perl.org
69 Please direct usage questions or support issues to the mailing list:
71 L<bioperl-l@bioperl.org>
73 rather than to the module maintainer directly. Many experienced and
74 reponsive experts will be able look at the problem and quickly
75 address it. Please include a thorough description of the problem
76 with code and data examples if at all possible.
80 Report bugs to the Bioperl bug tracking system to help us keep track
81 the bugs and their resolution. Bug reports can be submitted via the
84 http://bugzilla.open-bio.org/
86 =head1 AUTHOR - Will Spooner
88 Email whs@sanger.ac.uk
93 The rest of the documentation details each of the object methods.
94 Internal methods are usually preceded with a _
99 # Let the code begin...
100 package Bio
::Root
::Storable
;
103 use Data
::Dumper
qw( Dumper );
108 use vars
qw( $BINARY );
109 use base qw(Bio::Root::Root);
112 if( eval "require Storable" ){
113 Storable
->import( 'freeze', 'thaw' );
118 #----------------------------------------------------------------------
122 Arg [1] : -workdir => filesystem path,
123 -template => tmpfile template,
124 -suffix => tmpfile suffix,
125 Function : Builds a new Bio::Root::Storable inhereting object
126 Returntype: Bio::Root::Storable inhereting object
129 Example : $storable = Bio::Root::Storable->new()
134 my ($caller, @args) = @_;
135 my $self = $caller->SUPER::new
(@args);
136 $self->_initialise_storable;
140 #----------------------------------------------------------------------
142 =head2 _initialise_storable
144 Arg [1] : See 'new' method
145 Function : Initialises storable-specific attributes
153 sub _initialise_storable
{
155 my( $workdir, $template, $suffix ) =
156 $self->_rearrange([qw(WORKDIR TEMPLATE SUFFIX)], @_ );
157 $workdir && $self->workdir ( $workdir );
158 $template && $self->template( $template );
159 $suffix && $self->suffix ( $suffix );
165 #----------------------------------------------------------------------
169 Arg [1] : string (optional)
170 Function : Accessor for the file to write state into.
171 Should not normaly use as a setter - let Root::IO
175 Caller : Bio::Root::Storable->store
176 Example : my $statefile = $obj->statefile();
182 my $key = '_statefile';
185 if( @_ ){ $self->{$key} = shift }
187 if( ! $self->{$key} ){ # Create a new statefile
189 my $workdir = $self->workdir;
190 my $template = $self->template;
191 my $suffix = $self->suffix;
193 # TODO: add cleanup and unlink methods. For now, we'll keep the
194 # statefile hanging around.
195 my @args = ( CLEANUP
=>0, UNLINK
=>0 );
196 if( $template ){ push( @args, 'TEMPLATE' => $template )};
197 if( $workdir ){ push( @args, 'DIR' => $workdir )};
198 if( $suffix ){ push( @args, 'SUFFIX' => $suffix )};
199 my( $fh, $file ) = Bio
::Root
::IO
->new->tempfile( @args );
201 $self->{$key} = $file;
204 return $self->{$key};
207 #----------------------------------------------------------------------
211 Arg [1] : string (optional) (TODO - convert to array for x-platform)
212 Function : Accessor for the statefile directory. Defaults to File::Spec->tmpdir
216 Example : $obj->workdir('/tmp/foo');
221 my $key = '_workdir';
224 my $caller = join( ', ', (caller(0))[1..2] );
225 $self->{$key} && $self->debug("Overwriting workdir: probably bad!");
226 $self->{$key} = shift
228 # $self->{$key} ||= $Bio::Root::IO::TEMPDIR;
229 $self->{$key} ||= File
::Spec
->tmpdir();
230 return $self->{$key};
233 #----------------------------------------------------------------------
237 Arg [1] : string (optional)
238 Function : Accessor for the statefile template. Defaults to XXXXXXXX
242 Example : $obj->workdir('RES_XXXXXXXX');
247 my $key = '_template';
249 if( @_ ){ $self->{$key} = shift }
250 $self->{$key} ||= 'XXXXXXXX';
251 return $self->{$key};
254 #----------------------------------------------------------------------
258 Arg [1] : string (optional)
259 Function : Accessor for the statefile template.
263 Example : $obj->suffix('.state');
270 if( @_ ){ $self->{$key} = shift }
271 return $self->{$key};
274 #----------------------------------------------------------------------
276 =head2 new_retrievable
278 Arg [1] : Same as for 'new'
279 Function : Similar to store, except returns a 'skeleton' of the calling
280 object, rather than the statefile.
281 The skeleton can be repopulated by calling 'retrieve'. This
282 will be a clone of the original object.
283 Returntype: Bio::Root::Storable inhereting object
286 Example : my $skel = $obj->new_retrievable(); # skeleton
287 $skel->retrieve(); # clone
295 $self->_initialise_storable( @args );
297 if( $self->retrievable ){ return $self->clone } # Clone retrievable
298 return bless( { _statefile
=> $self->store(@args),
299 _workdir
=> $self->workdir,
300 _suffix
=> $self->suffix,
301 _template
=> $self->template,
302 _retrievable
=> 1 }, ref( $self ) );
305 #----------------------------------------------------------------------
310 Function : Reports whether the object is in 'skeleton' state, and the
311 'retrieve' method can be called.
315 Example : if( $obj->retrievable ){ $obj->retrieve }
321 if( @_ ){ $self->{_retrievable
} = shift }
322 return $self->{_retrievable
};
325 #----------------------------------------------------------------------
330 Function : Accessor for token attribute
331 Returntype: string. Whatever retrieve needs to retrieve.
332 This base implementation returns the statefile
335 Example : my $token = $obj->token();
341 return $self->statefile;
345 #----------------------------------------------------------------------
350 Function : Saves a serialised representation of the object structure
351 to disk. Returns the name of the file that the object was
357 Example : my $token = $obj->store();
363 my $statefile = $self->statefile;
364 my $store_obj = $self->serialise;
365 my $io = Bio
::Root
::IO
->new( ">$statefile" );
366 $io->_print( $store_obj );
367 $self->debug( "STORING $self to $statefile\n" );
371 #----------------------------------------------------------------------
376 Function : Prepares the the serialised representation of the object.
377 Object attribute names starting with '__' are skipped.
378 This is useful for those that do not serialise too well
380 Attributes are examined for other storable objects. If these
381 are found they are serialised seperately using 'new_retrievable'
385 Example : my $serialised = $obj->serialise();
392 # Create a new object of same class that is going to be serialised
393 my $store_obj = bless( {}, ref( $self ) );
395 my %retargs = ( -workdir
=>$self->workdir,
396 -suffix
=>$self->suffix,
397 -template
=>$self->template );
398 # Assume that other storable bio objects held by this object are
401 foreach my $key( keys( %$self ) ){
402 if( $key =~ /^__/ ){ next } # Ignore keys starting with '__'
403 my $value = $self->{$key};
406 if( ! ref( $value ) ){
407 $store_obj->{$key} = $value;
410 # Bio::Root::Storable obj: save placeholder
411 elsif( ref($value) =~ /^Bio::/ and $value->isa('Bio::Root::Storable') ){
412 # Bio::Root::Storable
413 $store_obj->{$key} = $value->new_retrievable( %retargs );
417 # Arrayref value. Look for Bio::Root::Storable objs
418 elsif( ref( $value ) eq 'ARRAY' ){
420 foreach my $val( @
$value ){
421 if( ref($val) =~ /^Bio::/ and $val->isa('Bio::Root::Storable') ){
422 push( @ary, $val->new_retrievable( %retargs ) );
424 else{ push( @ary, $val ) }
426 $store_obj->{$key} = \
@ary;
429 # Hashref value. Look for Bio::Root::Storable objs
430 elsif( ref( $value ) eq 'HASH' ){
432 foreach my $k2( keys %$value ){
433 my $val = $value->{$k2};
434 if( ref($val) =~ /^Bio::/ and $val->isa('Bio::Root::Storable') ){
435 $hash{$k2} = $val->new_retrievable( %retargs );
437 else{ $hash{$k2} = $val }
439 $store_obj->{$key} = \
%hash;
442 # Unknown, just add to the store object regardless
443 else{ $store_obj->{$key} = $value }
445 $store_obj->retrievable(0); # Once deserialised, obj not retrievable
446 return $self->_freeze( $store_obj );
450 #----------------------------------------------------------------------
454 Arg [1] : string; filesystem location of the state file to be retrieved
455 Function : Retrieves a stored object from disk.
456 Note that the retrieved object will be blessed into its original
458 Returntype: Bio::Root::Storable inhereting object
461 Example : my $obj = Bio::Root::Storable->retrieve( $token );
466 my( $caller, $statefile ) = @_;
469 my $class = ref( $caller ) || $caller;
471 # Is this a call on a retrievable object?
472 if( ref( $caller ) and
473 $caller->retrievable ){
475 $statefile = $self->statefile;
477 bless( $self, $class );
479 # Recover serialised object
480 if( ! -f
$statefile ){
481 $self->throw( "Token $statefile is not found" );
483 my $io = Bio
::Root
::IO
->new( $statefile );
485 my $state_str = $io->_readline('-raw'=>1);
487 # Dynamic-load modules required by stored object
490 for( my $i=0; $i<10; $i++ ){
491 eval{ $stored_obj = $self->_thaw( $state_str ) };
492 if( ! $@
){ $success=1; last }
494 if( $@
=~ /Cannot restore overloading(.*)/i ){
495 my $postmatch = $1; #'
496 if( $postmatch =~ /\(package +([\w\:]+)\)/ ) {
501 eval "require $package"; $self->throw($@
) if $@
;
503 else{ $self->throw($@
) }
505 if( ! $success ){ $self->throw("maximum number of requires exceeded" ) }
507 if( ! ref( $stored_obj ) ){
508 $self->throw( "Token $statefile returned no data" );
510 map{ $self->{$_} = $stored_obj->{$_} } keys %$stored_obj; # Copy hasheys
511 $self->retrievable(0);
513 # Maintain class of stored obj
517 #----------------------------------------------------------------------
523 Function : Returns a clone of the calling object
524 Returntype: Bio::Root::Storable inhereting object
527 Example : my $clone = $obj->clone();
533 my $frozen = $self->_freeze( $self );
534 return $self->_thaw( $frozen );
539 #----------------------------------------------------------------------
544 Function : Clears the stored object from disk
548 Example : $obj->remove();
554 if( -e
$self->statefile ){
555 unlink( $self->statefile );
560 #----------------------------------------------------------------------
565 Function : Converts whatever is in the the arg into a string.
566 Uses either Storable::freeze or Data::Dumper::Dump
567 depending on the value of $Bio::Root::BINARY
579 return freeze
( $data );
582 $Data::Dumper
::Purity
= 1;
583 return Data
::Dumper
->Dump( [\
$data],["*code"] );
587 #----------------------------------------------------------------------
592 Function : Converts the string into a perl 'whatever'.
593 Uses either Storable::thaw or eval depending on the
594 value of $Bio::Root::BINARY.
595 Note; the string arg should have been created with
596 the _freeze method, or strange things may occur!
607 if( $BINARY ){ return thaw
( $data ) }
610 $code = eval( $data ) ;
612 $self->throw( "eval: $@" );
614 ref( $code ) eq 'REF' ||
615 $self->throw( "Serialised string was not a scalar ref" );
623 #----------------------------------------------------------------------