JSON::PP::Monkey - JSON::PP with encoding fallbacks
version 0.1.0
use JSON::PP::Monkey; my $json = JSON::PP::Monkey->new->utf8->pretty ->allow_blessed->add_fallback('blessed', sub { +{ __BLESSED_ => "$_[1]" } }) ->allow_unknown->add_fallback('unknown', sub { +{ __UNKNOWN_ => "$_[1]" } }) $json->encode({ active => \1, io => \*STDOUT, foo => bless({}, 'foo')}); # { # "foo" : { # "__BLESSED_" : "foo=HASH(0x7fda11bc0fc8)" # }, # "active" : true, # "io" : { # "__UNKNOWN_" : "GLOB(0x7fda11029518)" # } # }
This is an experiment with a JSON encoder that can apply fallback conversions to blessed objects and unknowns.
The primary reason it has been created was to allow dumping arbitrary Perl data into JSON.
Unlike JSON::PP, JSON::XS, Cpanel::JSON::XS, "allow_blessed" must be enabled before blessed objects can be converted to JSON by invoking TO_JSON or stringifying bignums.
JSON::PP
JSON::XS
Cpanel::JSON::XS
TO_JSON
# { "x": <JSON encoding of $foo->TO_JSON> } JSON::PP::Monkey->new->allow_blessed->convert_blessed->encode({x => $foo}); # dies - allow_blessed is not enabled JSON::PP::Monkey->new->convert_blessed->encode({x => $foo}); # { "x": "999" } JSON::PP::Monkey->new->allow_blessed->convert_bignum->encode({x => Math::BigInt->new('999')}); # dies - allow_blessed is not enabled JSON::PP::Monkey->new->convert_bignum->encode({x => $foo});
Another difference is that the fallback conversion of objects into 'null' must be disabled explicitly (with "collapse_blessed") if it is unwanted. So
'null'
JSON::PP::Monkey->new->allow_blessed->collapse_blessed(0)->convert_blessed;
is the equivalent of
JSON::PP->new->convert_blessed;
in the sense they will convert objects with TO_JSON methods into JSON and bail on everything else.
The behavior of "allow_unknown" and "collapse_unknown" is analogous.
These API changes have been made to provide a more consistent behavior.
if objects will be encoded, allow_blessed must be enabled before any fallback (installed with "add_fallback", "convert_blessed", or "convert_bignum") can be applied.
allow_blessed
if objects will be encoded but the fallback conversion into "null" is unwanted, it should be disabled with "collapse_blessed".
"null"
if unknowns will be encoded, allow_unknown must be enabled before any fallback can be applied
allow_unknown
if unknowns will be encoded but the fallback conversion into "null" is unwanted, it should be disabled with "collapse_unknown".
Notice that the order of fallbacks is important:
$json = JSON::PP->new->utf8->allow_blessed->convert_bignum->convert_blessed;
will apply stringification to bignums before trying to check for TO_JSON methods. While
$json = JSON::PP->new->utf8->allow_blessed->convert_blessed->convert_bignum;
will check for TO_JSON methods (and apply them) before considering the stringification of bignums.
$json = $json->allow_blessed; $json = $json->allow_blessed($enable);
If enabled, allows to encode blessed references (or objects) via the current 'blessed' fallbacks or into 'null' (if "collapse_blessed" is enabled).
'blessed'
Defaults to disabled.
$json = $json->allow_unknown; $json = $json->allow_unknown($enable);
If enabled, allows to encode unknown references via the current 'unknown' fallbacks or into 'null' (if "collapse_unknown" is enabled).
'unknown'
$json = $json->collapse_blessed; $json = $json->collapse_blessed($enable);
If "allow_blessed" is enabled, an object is encoded into 'null' if no 'blessed' fallback applied.
Defaults to enabled. Only has effect if "allow_blessed" is enabled.
"allow_blessed"
$json = $json->collapse_unknown; $json = $json->collapse_unknown($enable);
If "allow_unknown" is enabled, an unknown is encoded into 'null' if no 'unknown' fallback applied.
Defaults to enabled. Only has effect if "allow_unknown" is enabled.
"allow_unknown"
$json = $json->convert_blessed;
Add a "blessed" fallback which applies to objects which have a "TO_JSON" method. Equivalent to
"blessed"
"TO_JSON"
$json = $json->add_fallback('blessed', sub { return unless $_[1]->can('TO_JSON'); return $_[1]->TO_JSON; });
Only has effect if "allow_blessed" is enabled.
$json = $json->convert_bignum;
Add a "blessed" fallback which applies to objects which are Math::BigInt or Math::BigFloat. Equivalent to
$json = $json->add_fallback('blessed', sub { return unless $_[1]->isa('Math::BigInt') || $_[1]->isa('Math::BigFloat'); return "$_[1]" });
$json = $json->add_fallback('blessed', $cb); $json = $json->add_fallback('unknown', $cb);
Add fallback conversions to be applied if:
a blessed ref is found and "allow_blessed" is enabled an unknown is found and "allow_unknown" is enabled
$case should be one of 'blessed' or 'unknown'.
$case
$cb is a subroutine which expects two arguments
$cb
sub { my ($json, $item, $case) = (shift, shift); ... }
Fallback subroutines are evaluated in list context. Their return is interpreted as below.
a non-empty list means the first element converted to JSON will be the encoding result
an empty list means the fallback did not match, and the next one should be tried
$json = $json->remove_fallback($case, $cb);
Adriano Ferreira <ferreira@cpan.org>
Adriano Ferreira <a.r.ferreira@gmail.com>
This software is copyright (c) 2017 by Adriano Ferreira.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
To install JSON::PP::Monkey, copy and paste the appropriate command in to your terminal.
cpanm
cpanm JSON::PP::Monkey
CPAN shell
perl -MCPAN -e shell install JSON::PP::Monkey
For more information on module installation, please visit the detailed CPAN module installation guide.