Data::Transform::ExplicitMetadata - Encode Perl values in a json-friendly way
use Data::Transform::ExplicitMetadata qw(encode decode); use JSON; my $val = encode($some_data_structure); $io->print( JSON::encode_json( $val )); my $data_structure_copy = decode($val);
Transforms an arbitrarily nested data structure into an analogous data structure composed of only simple scalars, arrayrefs and hashrefs that may be safely JSON-encoded, while retaining all the Perl-specific metadata about typeglobs, blessed and tied references, self-referential data, reference addresses, etc.
With a few exceptions, a copy of the original data structure can be recreated from the encoded version.
Accepts a single value and returns a value that may be safely passed to JSON::encode_json(). encode_json() cannot handle Perl-specific data like blessed references or typeglobs. Non-reference scalar values like numbers and strings are returned unchanged. For all references, encode() returns a hashref with these keys
String indicating the type of reference, as returned by Scalar::Util::reftype()
Memory address of the reference, as returned by Scalar::Util::refaddr()
Package this reference is blessed into, as returned by Scalar::Util::blessed.
Reference to the unblessed data.
The original value hidden by the tie() operation.
Flag indicating this reference was seen before
If the reference was not blessed or tied, then the __blessed and/or __tied keys will not be present.
__valueis generally a copy of the underlying data. For example, if the input value is an hashref, then __value will also be a hashref containing the input value's kays and values. For typeblobs and glob refs, __value will be a hashref with the keys NAME, PACKAGE, SCALAR, ARRAY, HASH, IO and CODE. For compiled regexps, __value will be a 2-element arrayref of the pattern and modifiers. For coderefs, __value will be the stringified reference, like "CODE=(0x12345678)". For v-strings and v-string refs, __value will by an arrayref containing the integers making up the v-string.
For tied objects,
__tiedwill be contain the original value hidden by tie() and __value will contain the tied data. The original data is retrieved by:
call tied() to get a copy of the tied data
localize the UNTIE method in the appropriate class
untie the variable
save a copy of the original value
localize the appropriate TIE* mythod to return the tied data
call tie() to retie the variable
__recursiveis true, then __value will contain a string representation of the first place this reference was seen in the data structure.
encode() handles arbitrarily nested data structures, meaning that values in the __values slot may also be encoded this way.
Accepts a single value and returns a copy of the data structure originally passed to encode(). __refaddr information is discarded and new copies of nested data structures is created. Self-referential data is re-linked to the appropriate placxe in the new copy. Blessed references are re-bless into the original packages.
Tied variables are re-tied by localizing the appropriate TIE* method to return the tied data. The variable's original data is filled in before calling tie().
The IO slot of typeglobs is recreated by opening the handle with the same descriptor number and open mode. It will first try fcntl() with F_GETFL to determine the open mode, falling back to using FileHandle::Fmode if it's available. Finally, it will first try re-opening the file descriptor in read mode, then write mode.
Coderefs cannot be decoded properly. They are recreated by returning a reference to a dummy sub that returns a message explaning the situation.
Anthony Brummett <email@example.com>
Copyright 2016, Anthony Brummett. This module is free software. It may be used, redistributed and/or modified under the same terms as Perl itself.