Storable#

📦 std

Serialise arbitrary Perl data structures to bytes, reconstruct them later, or deep-clone them in memory.

Storable turns a reference - to a scalar, array, hash, blessed object, or any tree built from them - into an opaque byte string that can be written to disk, sent over a socket, or fed back into the module to reproduce the original structure. The round trip preserves shared references, circular references, weak references, tied variables, regexp objects, and blessed classes (with STORABLE_freeze / STORABLE_thaw hooks honoured).

Two axes of choice cover every use:

  • Where the bytes go. freeze returns them as a string, store writes them to a named file, store_fd writes them to an open filehandle. thaw, retrieve, and fd_retrieve are the matching readers.

  • Byte order on the wire. freeze / store / store_fd use the host’s native byte order - fastest, but only portable between machines of the same endianness and integer size. The n-prefixed variants nfreeze, nstore, nstore_fd use network (big-endian) order and are portable across architectures. The reader side auto-detects which was used.

dclone is the in-memory shortcut for “I want a structurally independent copy of this data.” It serialises and immediately deserialises, so every element is freshly allocated and every STORABLE_freeze / STORABLE_thaw hook runs - which is the only safe way to clone objects that wrap non-SV resources (a PDL’s engine pointer, a tied variable’s backing state, a file handle).

file_magic and read_magic inspect a frozen payload without thawing it, returning a hash describing byte order, header size, and version metadata. Use them to validate untrusted input or to pick a reader before committing to a thaw.

This is Storable 3.41; Storable.pm is upstream’s, its engine native. An image written by perl5’s Storable reads here and the other way round.

Synopsis#

use Storable qw(nstore retrieve nfreeze thaw dclone);

my %config = (name => 'demo', ports => [80, 443], nested => { on => 1 });
nstore(\%config, 'config.sto');             # portable byte order
my $back = retrieve('config.sto');
print "$back->{name} @{ $back->{ports} }\n"; # demo 80 443

my $bytes = nfreeze([1, { two => 2 }]);      # a string, e.g. for a socket
print thaw($bytes)->[1]{two}, "\n";          # 2

my $deep = dclone(\%config);                # an independent copy
$deep->{ports}[0] = 8080;                   # %config keeps 80

package Counter;                            # what an object stores
sub STORABLE_freeze { my ($self, $cloning) = @_; return $self->{n} }
sub STORABLE_thaw   { my ($self, $cloning, $n) = @_; $self->{n} = $n }

The functions, written in Perl#

store and retrieve are exported by default, the rest on request.

  • store($ref, $file), nstore($ref, $file) - write to a file; lock_store, lock_nstore take an exclusive flock first.

  • retrieve($file), lock_retrieve($file) - read one back.

  • store_fd($ref, $fh), nstore_fd($ref, $fh), fd_retrieve($fh) - the same over an open filehandle.

  • freeze($ref), nfreeze($ref), thaw($string) - to and from a string.

  • file_magic($file), read_magic($string) - the header of an image as a hash, without reading it.

A writer dies on what it cannot store (“Can’t store CODE items”). A reader returns undef for a truncated image and dies for one that is no Storable image at all (“Magic number checking on storable string failed”, or a version it does not know). $Storable::canonical sorts hash keys, so equal data gives equal bytes; $Storable::Deparse and $Storable::Eval store and restore code references.

Differences from upstream#

Two, each where perl 5.44 with Storable.xs fails (t/81-xs-native/Storable/980-or-better.t):

  • An image whose length field asks for more memory than the process can get is a truncated image: the read returns undef. perl5 dies “Out of memory!”, ending the process.

  • Storable::pretrieve on a handle with nothing to read (opened, then closed) fails the image check; perl5 parses whatever an earlier freeze left in its buffer.

Functions#

Deep cloning#

dclone#

A deep copy of what a reference points to: every array, hash and scalar in it newly made, shared and circular references kept as they were, objects re-blessed, and STORABLE_freeze/STORABLE_thaw hooks run - in one step, without a byte string in between. Dies “Not a reference” for anything else, and “Can’t store CODE items” for a structure holding a code reference unless $Storable::Deparse and $Storable::Eval are set, as for freeze.

Inside a hook#

last_op_in_netorder#

True if the last store or retrieve used network byte order (nstore, nfreeze, or reading such an image), false after a native one. Not exportable: call it as Storable::last_op_in_netorder().

is_storing#

True while a store is running - inside a STORABLE_freeze hook, say - and false otherwise. Call it as Storable::is_storing().

is_retrieving#

True while a retrieve is running - inside a STORABLE_thaw hook, say - and false otherwise. Call it as Storable::is_retrieving().

Recursion limits#

stack_depth#

How deeply nested arrays a store or retrieve may follow before it dies “Max. recursion depth with nested structures exceeded”: $Storable::recursion_limit, 512 unless set (-1 for no limit).

stack_depth_hash#

The same for nested hashes: $Storable::recursion_limit_hash, 256 unless set (-1 for no limit).