Upgrade to Storable 1.0.6, from Raphael Manfredi.
[p5sagit/p5-mst-13.2.git] / ext / Storable / Storable.pm
CommitLineData
90826881 1;# $Id: Storable.pm,v 1.0.1.5 2000/10/26 17:10:18 ram Exp $
7a6a85bf 2;#
3;# Copyright (c) 1995-2000, Raphael Manfredi
4;#
9e21b3d0 5;# You may redistribute only under the same terms as Perl 5, as specified
6;# in the README file that comes with the distribution.
7a6a85bf 7;#
8;# $Log: Storable.pm,v $
90826881 9;# Revision 1.0.1.6 2000/11/05 17:20:25 ram
10;# patch6: increased version number
11;#
212e9bde 12;# Revision 1.0.1.5 2000/10/26 17:10:18 ram
13;# patch5: documented that store() and retrieve() can return undef
14;# patch5: added paragraph explaining the auto require for thaw hooks
15;#
16;# Revision 1.0.1.4 2000/10/23 18:02:57 ram
17;# patch4: protected calls to flock() for dos platform
18;# patch4: added logcarp emulation if they don't have Log::Agent
19;#
20;# $Log: Storable.pm,v $
9e21b3d0 21;# Revision 1.0 2000/09/01 19:40:41 ram
22;# Baseline for first official release.
7a6a85bf 23;#
24
25require DynaLoader;
26require Exporter;
27package Storable; @ISA = qw(Exporter DynaLoader);
28
29@EXPORT = qw(store retrieve);
30@EXPORT_OK = qw(
9e21b3d0 31 nstore store_fd nstore_fd fd_retrieve
7a6a85bf 32 freeze nfreeze thaw
33 dclone
9e21b3d0 34 retrieve_fd
dd19458b 35 lock_store lock_nstore lock_retrieve
7a6a85bf 36);
37
38use AutoLoader;
39use vars qw($forgive_me $VERSION);
40
90826881 41$VERSION = '1.006';
7a6a85bf 42*AUTOLOAD = \&AutoLoader::AUTOLOAD; # Grrr...
43
44#
45# Use of Log::Agent is optional
46#
47
48eval "use Log::Agent";
49
50unless (defined @Log::Agent::EXPORT) {
51 eval q{
52 sub logcroak {
53 require Carp;
54 Carp::croak(@_);
55 }
b29b780f 56 sub logcarp {
57 require Carp;
58 Carp::carp(@_);
59 }
7a6a85bf 60 };
61}
62
dd19458b 63#
64# They might miss :flock in Fcntl
65#
66
67BEGIN {
68 require Fcntl;
69 if (exists $Fcntl::EXPORT_TAGS{'flock'}) {
70 Fcntl->import(':flock');
71 } else {
72 eval q{
73 sub LOCK_SH () {1}
74 sub LOCK_EX () {2}
75 };
76 }
77}
78
7a6a85bf 79sub logcroak;
b29b780f 80sub logcarp;
7a6a85bf 81
9e21b3d0 82sub retrieve_fd { &fd_retrieve } # Backward compatibility
cb3d9de5 83
7a6a85bf 84bootstrap Storable;
851;
86__END__
87
88#
89# store
90#
91# Store target object hierarchy, identified by a reference to its root.
92# The stored object tree may later be retrieved to memory via retrieve.
93# Returns undef if an I/O error occurred, in which case the file is
94# removed.
95#
96sub store {
dd19458b 97 return _store(\&pstore, @_, 0);
7a6a85bf 98}
99
100#
101# nstore
102#
103# Same as store, but in network order.
104#
105sub nstore {
dd19458b 106 return _store(\&net_pstore, @_, 0);
107}
108
109#
110# lock_store
111#
112# Same as store, but flock the file first (advisory locking).
113#
114sub lock_store {
115 return _store(\&pstore, @_, 1);
116}
117
118#
119# lock_nstore
120#
121# Same as nstore, but flock the file first (advisory locking).
122#
123sub lock_nstore {
124 return _store(\&net_pstore, @_, 1);
7a6a85bf 125}
126
127# Internal store to file routine
128sub _store {
129 my $xsptr = shift;
130 my $self = shift;
dd19458b 131 my ($file, $use_locking) = @_;
7a6a85bf 132 logcroak "not a reference" unless ref($self);
dd19458b 133 logcroak "too many arguments" unless @_ == 2; # No @foo in arglist
7a6a85bf 134 local *FILE;
135 open(FILE, ">$file") || logcroak "can't create $file: $!";
136 binmode FILE; # Archaic systems...
dd19458b 137 if ($use_locking) {
f567092b 138 if ($^O eq 'dos') {
b29b780f 139 logcarp "Storable::lock_store: fcntl/flock emulation broken on $^O";
140 return undef;
f567092b 141 }
dd19458b 142 flock(FILE, LOCK_EX) ||
143 logcroak "can't get exclusive lock on $file: $!";
144 truncate FILE, 0;
145 # Unlocking will happen when FILE is closed
146 }
7a6a85bf 147 my $da = $@; # Don't mess if called from exception handler
148 my $ret;
149 # Call C routine nstore or pstore, depending on network order
150 eval { $ret = &$xsptr(*FILE, $self) };
151 close(FILE) or $ret = undef;
152 unlink($file) or warn "Can't unlink $file: $!\n" if $@ || !defined $ret;
153 logcroak $@ if $@ =~ s/\.?\n$/,/;
154 $@ = $da;
155 return $ret ? $ret : undef;
156}
157
158#
159# store_fd
160#
161# Same as store, but perform on an already opened file descriptor instead.
162# Returns undef if an I/O error occurred.
163#
164sub store_fd {
165 return _store_fd(\&pstore, @_);
166}
167
168#
169# nstore_fd
170#
171# Same as store_fd, but in network order.
172#
173sub nstore_fd {
174 my ($self, $file) = @_;
175 return _store_fd(\&net_pstore, @_);
176}
177
178# Internal store routine on opened file descriptor
179sub _store_fd {
180 my $xsptr = shift;
181 my $self = shift;
182 my ($file) = @_;
183 logcroak "not a reference" unless ref($self);
184 logcroak "too many arguments" unless @_ == 1; # No @foo in arglist
185 my $fd = fileno($file);
186 logcroak "not a valid file descriptor" unless defined $fd;
187 my $da = $@; # Don't mess if called from exception handler
188 my $ret;
189 # Call C routine nstore or pstore, depending on network order
190 eval { $ret = &$xsptr($file, $self) };
191 logcroak $@ if $@ =~ s/\.?\n$/,/;
192 $@ = $da;
193 return $ret ? $ret : undef;
194}
195
196#
197# freeze
198#
199# Store oject and its hierarchy in memory and return a scalar
200# containing the result.
201#
202sub freeze {
203 _freeze(\&mstore, @_);
204}
205
206#
207# nfreeze
208#
209# Same as freeze but in network order.
210#
211sub nfreeze {
212 _freeze(\&net_mstore, @_);
213}
214
215# Internal freeze routine
216sub _freeze {
217 my $xsptr = shift;
218 my $self = shift;
219 logcroak "not a reference" unless ref($self);
220 logcroak "too many arguments" unless @_ == 0; # No @foo in arglist
221 my $da = $@; # Don't mess if called from exception handler
222 my $ret;
223 # Call C routine mstore or net_mstore, depending on network order
224 eval { $ret = &$xsptr($self) };
225 logcroak $@ if $@ =~ s/\.?\n$/,/;
226 $@ = $da;
227 return $ret ? $ret : undef;
228}
229
230#
231# retrieve
232#
233# Retrieve object hierarchy from disk, returning a reference to the root
234# object of that tree.
235#
236sub retrieve {
dd19458b 237 _retrieve($_[0], 0);
238}
239
240#
241# lock_retrieve
242#
243# Same as retrieve, but with advisory locking.
244#
245sub lock_retrieve {
246 _retrieve($_[0], 1);
247}
248
249# Internal retrieve routine
250sub _retrieve {
251 my ($file, $use_locking) = @_;
7a6a85bf 252 local *FILE;
dd19458b 253 open(FILE, $file) || logcroak "can't open $file: $!";
7a6a85bf 254 binmode FILE; # Archaic systems...
255 my $self;
256 my $da = $@; # Could be from exception handler
dd19458b 257 if ($use_locking) {
b29b780f 258 if ($^O eq 'dos') {
259 logcarp "Storable::lock_store: fcntl/flock emulation broken on $^O";
260 return undef;
261 }
262 flock(FILE, LOCK_SH) || logcroak "can't get shared lock on $file: $!";
dd19458b 263 # Unlocking will happen when FILE is closed
264 }
7a6a85bf 265 eval { $self = pretrieve(*FILE) }; # Call C routine
266 close(FILE);
267 logcroak $@ if $@ =~ s/\.?\n$/,/;
268 $@ = $da;
269 return $self;
270}
271
272#
9e21b3d0 273# fd_retrieve
7a6a85bf 274#
275# Same as retrieve, but perform from an already opened file descriptor instead.
276#
9e21b3d0 277sub fd_retrieve {
7a6a85bf 278 my ($file) = @_;
279 my $fd = fileno($file);
280 logcroak "not a valid file descriptor" unless defined $fd;
281 my $self;
282 my $da = $@; # Could be from exception handler
283 eval { $self = pretrieve($file) }; # Call C routine
284 logcroak $@ if $@ =~ s/\.?\n$/,/;
285 $@ = $da;
286 return $self;
287}
288
289#
290# thaw
291#
292# Recreate objects in memory from an existing frozen image created
293# by freeze. If the frozen image passed is undef, return undef.
294#
295sub thaw {
296 my ($frozen) = @_;
297 return undef unless defined $frozen;
298 my $self;
299 my $da = $@; # Could be from exception handler
300 eval { $self = mretrieve($frozen) }; # Call C routine
301 logcroak $@ if $@ =~ s/\.?\n$/,/;
302 $@ = $da;
303 return $self;
304}
305
306=head1 NAME
307
308Storable - persistency for perl data structures
309
310=head1 SYNOPSIS
311
312 use Storable;
313 store \%table, 'file';
314 $hashref = retrieve('file');
315
316 use Storable qw(nstore store_fd nstore_fd freeze thaw dclone);
317
318 # Network order
319 nstore \%table, 'file';
320 $hashref = retrieve('file'); # There is NO nretrieve()
321
322 # Storing to and retrieving from an already opened file
323 store_fd \@array, \*STDOUT;
324 nstore_fd \%table, \*STDOUT;
9e21b3d0 325 $aryref = fd_retrieve(\*SOCKET);
326 $hashref = fd_retrieve(\*SOCKET);
7a6a85bf 327
328 # Serializing to memory
329 $serialized = freeze \%table;
330 %table_clone = %{ thaw($serialized) };
331
332 # Deep (recursive) cloning
333 $cloneref = dclone($ref);
334
dd19458b 335 # Advisory locking
336 use Storable qw(lock_store lock_nstore lock_retrieve)
337 lock_store \%table, 'file';
338 lock_nstore \%table, 'file';
339 $hashref = lock_retrieve('file');
340
7a6a85bf 341=head1 DESCRIPTION
342
343The Storable package brings persistency to your perl data structures
344containing SCALAR, ARRAY, HASH or REF objects, i.e. anything that can be
345convenientely stored to disk and retrieved at a later time.
346
347It can be used in the regular procedural way by calling C<store> with
348a reference to the object to be stored, along with the file name where
349the image should be written.
350The routine returns C<undef> for I/O problems or other internal error,
351a true value otherwise. Serious errors are propagated as a C<die> exception.
352
353To retrieve data stored to disk, use C<retrieve> with a file name,
354and the objects stored into that file are recreated into memory for you,
355a I<reference> to the root object being returned. In case an I/O error
356occurs while reading, C<undef> is returned instead. Other serious
357errors are propagated via C<die>.
358
359Since storage is performed recursively, you might want to stuff references
360to objects that share a lot of common data into a single array or hash
361table, and then store that object. That way, when you retrieve back the
362whole thing, the objects will continue to share what they originally shared.
363
364At the cost of a slight header overhead, you may store to an already
365opened file descriptor using the C<store_fd> routine, and retrieve
9e21b3d0 366from a file via C<fd_retrieve>. Those names aren't imported by default,
7a6a85bf 367so you will have to do that explicitely if you need those routines.
368The file descriptor you supply must be already opened, for read
369if you're going to retrieve and for write if you wish to store.
370
371 store_fd(\%table, *STDOUT) || die "can't store to stdout\n";
9e21b3d0 372 $hashref = fd_retrieve(*STDIN);
7a6a85bf 373
374You can also store data in network order to allow easy sharing across
375multiple platforms, or when storing on a socket known to be remotely
376connected. The routines to call have an initial C<n> prefix for I<network>,
377as in C<nstore> and C<nstore_fd>. At retrieval time, your data will be
378correctly restored so you don't have to know whether you're restoring
dd19458b 379from native or network ordered data. Double values are stored stringified
380to ensure portability as well, at the slight risk of loosing some precision
381in the last decimals.
7a6a85bf 382
9e21b3d0 383When using C<fd_retrieve>, objects are retrieved in sequence, one
7a6a85bf 384object (i.e. one recursive tree) per associated C<store_fd>.
385
386If you're more from the object-oriented camp, you can inherit from
387Storable and directly store your objects by invoking C<store> as
388a method. The fact that the root of the to-be-stored tree is a
389blessed reference (i.e. an object) is special-cased so that the
390retrieve does not provide a reference to that object but rather the
391blessed object reference itself. (Otherwise, you'd get a reference
392to that blessed object).
393
394=head1 MEMORY STORE
395
396The Storable engine can also store data into a Perl scalar instead, to
397later retrieve them. This is mainly used to freeze a complex structure in
398some safe compact memory place (where it can possibly be sent to another
399process via some IPC, since freezing the structure also serializes it in
400effect). Later on, and maybe somewhere else, you can thaw the Perl scalar
401out and recreate the original complex structure in memory.
402
403Surprisingly, the routines to be called are named C<freeze> and C<thaw>.
404If you wish to send out the frozen scalar to another machine, use
405C<nfreeze> instead to get a portable image.
406
407Note that freezing an object structure and immediately thawing it
408actually achieves a deep cloning of that structure:
409
410 dclone(.) = thaw(freeze(.))
411
412Storable provides you with a C<dclone> interface which does not create
413that intermediary scalar but instead freezes the structure in some
414internal memory space and then immediatly thaws it out.
415
dd19458b 416=head1 ADVISORY LOCKING
417
418The C<lock_store> and C<lock_nstore> routine are equivalent to C<store>
419and C<nstore>, only they get an exclusive lock on the file before
420writing. Likewise, C<lock_retrieve> performs as C<retrieve>, but also
421gets a shared lock on the file before reading.
422
423Like with any advisory locking scheme, the protection only works if
424you systematically use C<lock_store> and C<lock_retrieve>. If one
425side of your application uses C<store> whilst the other uses C<lock_retrieve>,
426you will get no protection at all.
427
428The internal advisory locking is implemented using Perl's flock() routine.
429If your system does not support any form of flock(), or if you share
430your files across NFS, you might wish to use other forms of locking by
431using modules like LockFile::Simple which lock a file using a filesystem
432entry, instead of locking the file descriptor.
433
7a6a85bf 434=head1 SPEED
435
436The heart of Storable is written in C for decent speed. Extra low-level
437optimization have been made when manipulating perl internals, to
438sacrifice encapsulation for the benefit of a greater speed.
439
440=head1 CANONICAL REPRESENTATION
441
442Normally Storable stores elements of hashes in the order they are
443stored internally by Perl, i.e. pseudo-randomly. If you set
444C<$Storable::canonical> to some C<TRUE> value, Storable will store
445hashes with the elements sorted by their key. This allows you to
446compare data structures by comparing their frozen representations (or
447even the compressed frozen representations), which can be useful for
448creating lookup tables for complicated queries.
449
450Canonical order does not imply network order, those are two orthogonal
451settings.
452
453=head1 ERROR REPORTING
454
455Storable uses the "exception" paradigm, in that it does not try to workaround
456failures: if something bad happens, an exception is generated from the
457caller's perspective (see L<Carp> and C<croak()>). Use eval {} to trap
458those exceptions.
459
460When Storable croaks, it tries to report the error via the C<logcroak()>
461routine from the C<Log::Agent> package, if it is available.
462
212e9bde 463Normal errors are reported by having store() or retrieve() return C<undef>.
464Such errors are usually I/O errors (or truncated stream errors at retrieval).
465
7a6a85bf 466=head1 WIZARDS ONLY
467
468=head2 Hooks
469
470Any class may define hooks that will be called during the serialization
471and deserialization process on objects that are instances of that class.
472Those hooks can redefine the way serialization is performed (and therefore,
473how the symetrical deserialization should be conducted).
474
475Since we said earlier:
476
477 dclone(.) = thaw(freeze(.))
478
479everything we say about hooks should also hold for deep cloning. However,
480hooks get to know whether the operation is a mere serialization, or a cloning.
481
482Therefore, when serializing hooks are involved,
483
484 dclone(.) <> thaw(freeze(.))
485
486Well, you could keep them in sync, but there's no guarantee it will always
487hold on classes somebody else wrote. Besides, there is little to gain in
488doing so: a serializing hook could only keep one attribute of an object,
489which is probably not what should happen during a deep cloning of that
490same object.
491
492Here is the hooking interface:
493
494=over
495
496=item C<STORABLE_freeze> I<obj>, I<cloning>
497
498The serializing hook, called on the object during serialization. It can be
499inherited, or defined in the class itself, like any other method.
500
501Arguments: I<obj> is the object to serialize, I<cloning> is a flag indicating
502whether we're in a dclone() or a regular serialization via store() or freeze().
503
504Returned value: A LIST C<($serialized, $ref1, $ref2, ...)> where $serialized
505is the serialized form to be used, and the optional $ref1, $ref2, etc... are
506extra references that you wish to let the Storable engine serialize.
507
508At deserialization time, you will be given back the same LIST, but all the
509extra references will be pointing into the deserialized structure.
510
511The B<first time> the hook is hit in a serialization flow, you may have it
512return an empty list. That will signal the Storable engine to further
513discard that hook for this class and to therefore revert to the default
514serialization of the underlying Perl data. The hook will again be normally
515processed in the next serialization.
516
517Unless you know better, serializing hook should always say:
518
519 sub STORABLE_freeze {
520 my ($self, $cloning) = @_;
521 return if $cloning; # Regular default serialization
522 ....
523 }
524
525in order to keep reasonable dclone() semantics.
526
527=item C<STORABLE_thaw> I<obj>, I<cloning>, I<serialized>, ...
528
529The deserializing hook called on the object during deserialization.
530But wait. If we're deserializing, there's no object yet... right?
531
532Wrong: the Storable engine creates an empty one for you. If you know Eiffel,
533you can view C<STORABLE_thaw> as an alternate creation routine.
534
535This means the hook can be inherited like any other method, and that
536I<obj> is your blessed reference for this particular instance.
537
538The other arguments should look familiar if you know C<STORABLE_freeze>:
539I<cloning> is true when we're part of a deep clone operation, I<serialized>
540is the serialized string you returned to the engine in C<STORABLE_freeze>,
541and there may be an optional list of references, in the same order you gave
542them at serialization time, pointing to the deserialized objects (which
543have been processed courtesy of the Storable engine).
544
212e9bde 545When the Storable engine does not find any C<STORABLE_thaw> hook routine,
546it tries to load the class by requiring the package dynamically (using
547the blessed package name), and then re-attempts the lookup. If at that
548time the hook cannot be located, the engine croaks. Note that this mechanism
549will fail if you define several classes in the same file, but perlmod(1)
550warned you.
551
7a6a85bf 552It is up to you to use these information to populate I<obj> the way you want.
553
554Returned value: none.
555
556=back
557
558=head2 Predicates
559
560Predicates are not exportable. They must be called by explicitely prefixing
561them with the Storable package name.
562
563=over
564
565=item C<Storable::last_op_in_netorder>
566
567The C<Storable::last_op_in_netorder()> predicate will tell you whether
568network order was used in the last store or retrieve operation. If you
569don't know how to use this, just forget about it.
570
571=item C<Storable::is_storing>
572
573Returns true if within a store operation (via STORABLE_freeze hook).
574
575=item C<Storable::is_retrieving>
576
577Returns true if within a retrieve operation, (via STORABLE_thaw hook).
578
579=back
580
581=head2 Recursion
582
583With hooks comes the ability to recurse back to the Storable engine. Indeed,
584hooks are regular Perl code, and Storable is convenient when it comes to
585serialize and deserialize things, so why not use it to handle the
586serialization string?
587
588There are a few things you need to know however:
589
590=over
591
592=item *
593
594You can create endless loops if the things you serialize via freeze()
595(for instance) point back to the object we're trying to serialize in the hook.
596
597=item *
598
599Shared references among objects will not stay shared: if we're serializing
600the list of object [A, C] where both object A and C refer to the SAME object
601B, and if there is a serializing hook in A that says freeze(B), then when
602deserializing, we'll get [A', C'] where A' refers to B', but C' refers to D,
603a deep clone of B'. The topology was not preserved.
604
605=back
606
607That's why C<STORABLE_freeze> lets you provide a list of references
608to serialize. The engine guarantees that those will be serialized in the
609same context as the other objects, and therefore that shared objects will
610stay shared.
611
612In the above [A, C] example, the C<STORABLE_freeze> hook could return:
613
614 ("something", $self->{B})
615
616and the B part would be serialized by the engine. In C<STORABLE_thaw>, you
617would get back the reference to the B' object, deserialized for you.
618
619Therefore, recursion should normally be avoided, but is nonetheless supported.
620
621=head2 Deep Cloning
622
623There is a new Clone module available on CPAN which implements deep cloning
624natively, i.e. without freezing to memory and thawing the result. It is
625aimed to replace Storable's dclone() some day. However, it does not currently
626support Storable hooks to redefine the way deep cloning is performed.
627
628=head1 EXAMPLES
629
630Here are some code samples showing a possible usage of Storable:
631
632 use Storable qw(store retrieve freeze thaw dclone);
633
634 %color = ('Blue' => 0.1, 'Red' => 0.8, 'Black' => 0, 'White' => 1);
635
636 store(\%color, '/tmp/colors') or die "Can't store %a in /tmp/colors!\n";
637
638 $colref = retrieve('/tmp/colors');
639 die "Unable to retrieve from /tmp/colors!\n" unless defined $colref;
640 printf "Blue is still %lf\n", $colref->{'Blue'};
641
642 $colref2 = dclone(\%color);
643
644 $str = freeze(\%color);
645 printf "Serialization of %%color is %d bytes long.\n", length($str);
646 $colref3 = thaw($str);
647
648which prints (on my machine):
649
650 Blue is still 0.100000
651 Serialization of %color is 102 bytes long.
652
653=head1 WARNING
654
655If you're using references as keys within your hash tables, you're bound
656to disapointment when retrieving your data. Indeed, Perl stringifies
657references used as hash table keys. If you later wish to access the
658items via another reference stringification (i.e. using the same
659reference that was used for the key originally to record the value into
660the hash table), it will work because both references stringify to the
661same string.
662
663It won't work across a C<store> and C<retrieve> operations however, because
664the addresses in the retrieved objects, which are part of the stringified
665references, will probably differ from the original addresses. The
666topology of your structure is preserved, but not hidden semantics
667like those.
668
669On platforms where it matters, be sure to call C<binmode()> on the
670descriptors that you pass to Storable functions.
671
672Storing data canonically that contains large hashes can be
673significantly slower than storing the same data normally, as
674temprorary arrays to hold the keys for each hash have to be allocated,
675populated, sorted and freed. Some tests have shown a halving of the
676speed of storing -- the exact penalty will depend on the complexity of
677your data. There is no slowdown on retrieval.
678
679=head1 BUGS
680
681You can't store GLOB, CODE, FORMLINE, etc... If you can define
682semantics for those operations, feel free to enhance Storable so that
683it can deal with them.
684
685The store functions will C<croak> if they run into such references
686unless you set C<$Storable::forgive_me> to some C<TRUE> value. In that
687case, the fatal message is turned in a warning and some
688meaningless string is stored instead.
689
690Setting C<$Storable::canonical> may not yield frozen strings that
691compare equal due to possible stringification of numbers. When the
692string version of a scalar exists, it is the form stored, therefore
693if you happen to use your numbers as strings between two freezing
694operations on the same data structures, you will get different
695results.
696
dd19458b 697When storing doubles in network order, their value is stored as text.
698However, you should also not expect non-numeric floating-point values
699such as infinity and "not a number" to pass successfully through a
700nstore()/retrieve() pair.
701
702As Storable neither knows nor cares about character sets (although it
703does know that characters may be more than eight bits wide), any difference
704in the interpretation of character codes between a host and a target
705system is your problem. In particular, if host and target use different
706code points to represent the characters used in the text representation
707of floating-point numbers, you will not be able be able to exchange
708floating-point data, even with nstore().
709
7a6a85bf 710=head1 CREDITS
711
712Thank you to (in chronological order):
713
714 Jarkko Hietaniemi <jhi@iki.fi>
715 Ulrich Pfeifer <pfeifer@charly.informatik.uni-dortmund.de>
716 Benjamin A. Holzman <bah@ecnvantage.com>
717 Andrew Ford <A.Ford@ford-mason.co.uk>
718 Gisle Aas <gisle@aas.no>
719 Jeff Gresham <gresham_jeffrey@jpmorgan.com>
720 Murray Nesbitt <murray@activestate.com>
721 Marc Lehmann <pcg@opengroup.org>
9e21b3d0 722 Justin Banks <justinb@wamnet.com>
723 Jarkko Hietaniemi <jhi@iki.fi> (AGAIN, as perl 5.7.0 Pumpkin!)
dd19458b 724 Salvador Ortiz Garcia <sog@msg.com.mx>
725 Dominic Dunlop <domo@computer.org>
726 Erik Haugan <erik@solbors.no>
7a6a85bf 727
728for their bug reports, suggestions and contributions.
729
730Benjamin Holzman contributed the tied variable support, Andrew Ford
731contributed the canonical order for hashes, and Gisle Aas fixed
732a few misunderstandings of mine regarding the Perl internals,
733and optimized the emission of "tags" in the output streams by
734simply counting the objects instead of tagging them (leading to
735a binary incompatibility for the Storable image starting at version
7360.6--older images are of course still properly understood).
737Murray Nesbitt made Storable thread-safe. Marc Lehmann added overloading
738and reference to tied items support.
739
740=head1 TRANSLATIONS
741
742There is a Japanese translation of this man page available at
743http://member.nifty.ne.jp/hippo2000/perltips/storable.htm ,
744courtesy of Kawai, Takanori <kawai@nippon-rad.co.jp>.
745
746=head1 AUTHOR
747
748Raphael Manfredi F<E<lt>Raphael_Manfredi@pobox.comE<gt>>
749
750=head1 SEE ALSO
751
752Clone(3).
753
754=cut
755