2 # BioPerl module for Bio::Root::Storable
4 # Please direct questions and support issues to <bioperl-l@bioperl.org>
6 # Cared for by Will Spooner <whs@sanger.ac.uk>
8 # Copyright Will Spooner <whs@sanger.ac.uk>
10 # You may distribute this module under the same terms as perl itself
12 # POD documentation - main docs before the code
16 Bio::Root::Storable - object serialisation methods
20 my $storable = Bio::Root::Storable->new();
22 # Store/retrieve using class retriever
23 my $token = $storable->store();
24 my $storable2 = Bio::Root::Storable->retrieve( $token );
26 # Store/retrieve using object retriever
27 my $storable2 = $storable->new_retrievable();
28 $storable2->retrieve();
33 Generic module that allows objects to be safely stored/retrieved from
34 disk. Can be inhereted by any BioPerl object. As it will not usually
35 be the first class in the inheretence list, _initialise_storable()
36 should be called during object instantiation.
38 Object storage is recursive; If the object being stored contains other
39 storable objects, these will be stored seperately, and replaced by a
40 skeleton object in the parent heirarchy. When the parent is later
41 retrieved, its children remain in the skeleton state until explicitly
42 retrieved by the parent. This lazy-retrieve approach has obvious
43 memory efficiency benefits for certain applications.
46 By default, objects are stored in binary format (using the Perl
47 Storable module). Earlier versions of Perl5 do not include Storable as
48 a core module. If this is the case, ASCII object storage (using the
49 Perl Data::Dumper module) is used instead.
51 ASCII storage can be enabled by default by setting the value of
52 $Bio::Root::Storable::BINARY to false.
60 User feedback is an integral part of the evolution of this and other
61 Bioperl modules. Send your comments and suggestions preferably to one
62 of the Bioperl mailing lists. Your participation is much appreciated.
64 bioperl-l@bio.perl.org
68 Please direct usage questions or support issues to the mailing list:
70 I<bioperl-l@bioperl.org>
72 rather than to the module maintainer directly. Many experienced and
73 reponsive experts will be able look at the problem and quickly
74 address it. Please include a thorough description of the problem
75 with code and data examples if at all possible.
79 Report bugs to the Bioperl bug tracking system to help us keep track
80 the bugs and their resolution. Bug reports can be submitted via the
83 http://bugzilla.open-bio.org/
85 =head1 AUTHOR - Will Spooner
87 Email whs@sanger.ac.uk
92 The rest of the documentation details each of the object methods.
93 Internal methods are usually preceded with a _
98 # Let the code begin...
99 package Bio
::Root
::Storable
;
102 use Data
::Dumper
qw( Dumper );
107 use vars
qw( $BINARY );
108 use base qw(Bio::Root::Root);
111 if( eval "require Storable" ){
112 Storable
->import( 'freeze', 'thaw' );
117 #----------------------------------------------------------------------
121 Arg [1] : -workdir => filesystem path,
122 -template => tmpfile template,
123 -suffix => tmpfile suffix,
124 Function : Builds a new Bio::Root::Storable inhereting object
125 Returntype: Bio::Root::Storable inhereting object
128 Example : $storable = Bio::Root::Storable->new()
133 my ($caller, @args) = @_;
134 my $self = $caller->SUPER::new
(@args);
135 $self->_initialise_storable;
139 #----------------------------------------------------------------------
141 =head2 _initialise_storable
143 Arg [1] : See 'new' method
144 Function : Initialises storable-specific attributes
152 sub _initialise_storable
{
154 my( $workdir, $template, $suffix ) =
155 $self->_rearrange([qw(WORKDIR TEMPLATE SUFFIX)], @_ );
156 $workdir && $self->workdir ( $workdir );
157 $template && $self->template( $template );
158 $suffix && $self->suffix ( $suffix );
164 #----------------------------------------------------------------------
168 Arg [1] : string (optional)
169 Function : Accessor for the file to write state into.
170 Should not normaly use as a setter - let Root::IO
174 Caller : Bio::Root::Storable->store
175 Example : my $statefile = $obj->statefile();
181 my $key = '_statefile';
184 if( @_ ){ $self->{$key} = shift }
186 if( ! $self->{$key} ){ # Create a new statefile
188 my $workdir = $self->workdir;
189 my $template = $self->template;
190 my $suffix = $self->suffix;
192 # TODO: add cleanup and unlink methods. For now, we'll keep the
193 # statefile hanging around.
194 my @args = ( CLEANUP
=>0, UNLINK
=>0 );
195 if( $template ){ push( @args, 'TEMPLATE' => $template )};
196 if( $workdir ){ push( @args, 'DIR' => $workdir )};
197 if( $suffix ){ push( @args, 'SUFFIX' => $suffix )};
198 my( $fh, $file ) = Bio
::Root
::IO
->new->tempfile( @args );
200 $self->{$key} = $file;
203 return $self->{$key};
206 #----------------------------------------------------------------------
210 Arg [1] : string (optional) (TODO - convert to array for x-platform)
211 Function : Accessor for the statefile directory. Defaults to File::Spec->tmpdir
215 Example : $obj->workdir('/tmp/foo');
220 my $key = '_workdir';
223 my $caller = join( ', ', (caller(0))[1..2] );
224 $self->{$key} && $self->debug("Overwriting workdir: probably bad!");
225 $self->{$key} = shift
227 # $self->{$key} ||= $Bio::Root::IO::TEMPDIR;
228 $self->{$key} ||= File
::Spec
->tmpdir();
229 return $self->{$key};
232 #----------------------------------------------------------------------
236 Arg [1] : string (optional)
237 Function : Accessor for the statefile template. Defaults to XXXXXXXX
241 Example : $obj->workdir('RES_XXXXXXXX');
246 my $key = '_template';
248 if( @_ ){ $self->{$key} = shift }
249 $self->{$key} ||= 'XXXXXXXX';
250 return $self->{$key};
253 #----------------------------------------------------------------------
257 Arg [1] : string (optional)
258 Function : Accessor for the statefile template.
262 Example : $obj->suffix('.state');
269 if( @_ ){ $self->{$key} = shift }
270 return $self->{$key};
273 #----------------------------------------------------------------------
275 =head2 new_retrievable
277 Arg [1] : Same as for 'new'
278 Function : Similar to store, except returns a 'skeleton' of the calling
279 object, rather than the statefile.
280 The skeleton can be repopulated by calling 'retrieve'. This
281 will be a clone of the original object.
282 Returntype: Bio::Root::Storable inhereting object
285 Example : my $skel = $obj->new_retrievable(); # skeleton
286 $skel->retrieve(); # clone
294 $self->_initialise_storable( @args );
296 if( $self->retrievable ){ return $self->clone } # Clone retrievable
297 return bless( { _statefile
=> $self->store(@args),
298 _workdir
=> $self->workdir,
299 _suffix
=> $self->suffix,
300 _template
=> $self->template,
301 _retrievable
=> 1 }, ref( $self ) );
304 #----------------------------------------------------------------------
309 Function : Reports whether the object is in 'skeleton' state, and the
310 'retrieve' method can be called.
314 Example : if( $obj->retrievable ){ $obj->retrieve }
320 if( @_ ){ $self->{_retrievable
} = shift }
321 return $self->{_retrievable
};
324 #----------------------------------------------------------------------
329 Function : Accessor for token attribute
330 Returntype: string. Whatever retrieve needs to retrieve.
331 This base implementation returns the statefile
334 Example : my $token = $obj->token();
340 return $self->statefile;
344 #----------------------------------------------------------------------
349 Function : Saves a serialised representation of the object structure
350 to disk. Returns the name of the file that the object was
356 Example : my $token = $obj->store();
362 my $statefile = $self->statefile;
363 my $store_obj = $self->serialise;
364 my $io = Bio
::Root
::IO
->new( ">$statefile" );
365 $io->_print( $store_obj );
366 $self->debug( "STORING $self to $statefile\n" );
370 #----------------------------------------------------------------------
375 Function : Prepares the the serialised representation of the object.
376 Object attribute names starting with '__' are skipped.
377 This is useful for those that do not serialise too well
379 Attributes are examined for other storable objects. If these
380 are found they are serialised seperately using 'new_retrievable'
384 Example : my $serialised = $obj->serialise();
391 # Create a new object of same class that is going to be serialised
392 my $store_obj = bless( {}, ref( $self ) );
394 my %retargs = ( -workdir
=>$self->workdir,
395 -suffix
=>$self->suffix,
396 -template
=>$self->template );
397 # Assume that other storable bio objects held by this object are
400 foreach my $key( keys( %$self ) ){
401 if( $key =~ /^__/ ){ next } # Ignore keys starting with '__'
402 my $value = $self->{$key};
405 if( ! ref( $value ) ){
406 $store_obj->{$key} = $value;
409 # Bio::Root::Storable obj: save placeholder
410 elsif( ref($value) =~ /^Bio::/ and $value->isa('Bio::Root::Storable') ){
411 # Bio::Root::Storable
412 $store_obj->{$key} = $value->new_retrievable( %retargs );
416 # Arrayref value. Look for Bio::Root::Storable objs
417 elsif( ref( $value ) eq 'ARRAY' ){
419 foreach my $val( @
$value ){
420 if( ref($val) =~ /^Bio::/ and $val->isa('Bio::Root::Storable') ){
421 push( @ary, $val->new_retrievable( %retargs ) );
423 else{ push( @ary, $val ) }
425 $store_obj->{$key} = \
@ary;
428 # Hashref value. Look for Bio::Root::Storable objs
429 elsif( ref( $value ) eq 'HASH' ){
431 foreach my $k2( keys %$value ){
432 my $val = $value->{$k2};
433 if( ref($val) =~ /^Bio::/ and $val->isa('Bio::Root::Storable') ){
434 $hash{$k2} = $val->new_retrievable( %retargs );
436 else{ $hash{$k2} = $val }
438 $store_obj->{$key} = \
%hash;
441 # Unknown, just add to the store object regardless
442 else{ $store_obj->{$key} = $value }
444 $store_obj->retrievable(0); # Once deserialised, obj not retrievable
445 return $self->_freeze( $store_obj );
449 #----------------------------------------------------------------------
453 Arg [1] : string; filesystem location of the state file to be retrieved
454 Function : Retrieves a stored object from disk.
455 Note that the retrieved object will be blessed into its original
457 Returntype: Bio::Root::Storable inhereting object
460 Example : my $obj = Bio::Root::Storable->retrieve( $token );
465 my( $caller, $statefile ) = @_;
468 my $class = ref( $caller ) || $caller;
470 # Is this a call on a retrievable object?
471 if( ref( $caller ) and
472 $caller->retrievable ){
474 $statefile = $self->statefile;
476 bless( $self, $class );
478 # Recover serialised object
479 if( ! -f
$statefile ){
480 $self->throw( "Token $statefile is not found" );
482 my $io = Bio
::Root
::IO
->new( $statefile );
484 my $state_str = $io->_readline('-raw'=>1);
486 # Dynamic-load modules required by stored object
489 for( my $i=0; $i<10; $i++ ){
490 eval{ $stored_obj = $self->_thaw( $state_str ) };
491 if( ! $@
){ $success=1; last }
493 if( $@
=~ /Cannot restore overloading(.*)/i ){
494 my $postmatch = $1; #'
495 if( $postmatch =~ /\(package +([\w\:]+)\)/ ) {
500 eval "require $package"; $self->throw($@
) if $@
;
502 else{ $self->throw($@
) }
504 if( ! $success ){ $self->throw("maximum number of requires exceeded" ) }
506 if( ! ref( $stored_obj ) ){
507 $self->throw( "Token $statefile returned no data" );
509 map{ $self->{$_} = $stored_obj->{$_} } keys %$stored_obj; # Copy hasheys
510 $self->retrievable(0);
512 # Maintain class of stored obj
516 #----------------------------------------------------------------------
522 Function : Returns a clone of the calling object
523 Returntype: Bio::Root::Storable inhereting object
526 Example : my $clone = $obj->clone();
532 my $frozen = $self->_freeze( $self );
533 return $self->_thaw( $frozen );
538 #----------------------------------------------------------------------
543 Function : Clears the stored object from disk
547 Example : $obj->remove();
553 if( -e
$self->statefile ){
554 unlink( $self->statefile );
559 #----------------------------------------------------------------------
564 Function : Converts whatever is in the the arg into a string.
565 Uses either Storable::freeze or Data::Dumper::Dump
566 depending on the value of $Bio::Root::BINARY
578 return freeze
( $data );
581 $Data::Dumper
::Purity
= 1;
582 return Data
::Dumper
->Dump( [\
$data],["*code"] );
586 #----------------------------------------------------------------------
591 Function : Converts the string into a perl 'whatever'.
592 Uses either Storable::thaw or eval depending on the
593 value of $Bio::Root::BINARY.
594 Note; the string arg should have been created with
595 the _freeze method, or strange things may occur!
606 if( $BINARY ){ return thaw
( $data ) }
609 $code = eval( $data ) ;
611 $self->throw( "eval: $@" );
613 ref( $code ) eq 'REF' ||
614 $self->throw( "Serialised string was not a scalar ref" );
622 #----------------------------------------------------------------------