Modules · Data · 0.09
Struct::Codec
A Perl structure to bytes and back, with nothing lost.
A cache holds bytes and a program holds structures, and on a small value the codec in between is most of the cost. Struct::Codec gives nothing up: strings stay strings, shared references stay shared, objects stay blessed. It publishes a C interface so another XS module encodes straight into memory it owns.
use Struct::Codec qw(struct_encode struct_decode);
my $roles = ['admin', 'ops'];
my $data = { user => 'ada', zip => '007', n => 3, roles => $roles, again => $roles };
my $copy = struct_decode(struct_encode($data));
print "$copy->{zip}\n"; # 007, still a string
print $copy->{roles} == $copy->{again} ? "shared\n" : "two copies\n"; # shared
What you get
-
What comes back the same
A string is a string and a number a number:
"007"comes back"007". The UTF-8 flag survives, on strings and on hash keys, and on perl 5.36 and later a boolean comes back a boolean. -
Shared, cyclic and blessed
References that were shared are shared again and a cycle is a cycle again. A blessed referent comes back blessed, with nothing called on it: no
FREEZE, noTHAW. -
What changes, said
A weak reference comes back strong, a dualvar keeps its string, and before perl 5.36 a boolean comes back as 1 or the empty string.
-
Fast on small values
Storable takes 1.7 microseconds to freeze and thaw a five-key hash. In its POD's measurement this is about three times faster, as JSON is, without giving up what JSON does.
In use
use Struct::Codec qw(struct_encode struct_decode);
package Point { sub new { my ($c, %a) = @_; bless {%a}, $c } }
my $p = Point->new(x => 1, y => 2);
my $loop = { name => 'loop' };
$loop->{self} = $loop; # a cycle
my ($p2, $loop2) = @{ struct_decode(struct_encode([$p, $loop])) };
print ref $p2, " at $p2->{x},$p2->{y}\n"; # Point at 1,2
print $loop2->{self} == $loop2 ? "a cycle again\n" : "broken\n";
For C
sc_abi.h, resolved at run time through Struct::Codec::_abi_ptr: another XS module encodes a value straight into memory it owns and decodes one straight out, with no Perl call in between and no link-time coupling.