NAME
JSON::PP::Monkey - JSON::PP with encoding fallbacks
VERSION
version 0.1.0
SYNOPSIS
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)"
# }
# }
DESCRIPTION
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.
CAVEATS
REVISED API
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.
# { "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
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.if objects will be encoded but the fallback conversion into
"null"
is unwanted, it should be disabled with "collapse_blessed".if unknowns will be encoded,
allow_unknown
must be enabled before any fallback can be appliedif unknowns will be encoded but the fallback conversion into
"null"
is unwanted, it should be disabled with "collapse_unknown".
FALLBACK ORDER
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.
METHODS
allow_blessed
$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).
Defaults to disabled.
allow_unknown
$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).
Defaults to disabled.
collapse_blessed
$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.
collapse_unknown
$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.
convert_blessed
$json = $json->convert_blessed;
Add a "blessed"
fallback which applies to objects which have a "TO_JSON"
method. Equivalent to
$json = $json->add_fallback('blessed', sub {
return unless $_[1]->can('TO_JSON');
return $_[1]->TO_JSON;
});
Only has effect if "allow_blessed"
is enabled.
convert_bignum
$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]"
});
Only has effect if "allow_blessed"
is enabled.
add_fallback
$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'
.
$cb
is a subroutine which expects two arguments
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
remove_fallback
$json = $json->remove_fallback($case, $cb);
AUTHOR
Adriano Ferreira <ferreira@cpan.org>
CONTRIBUTOR
Adriano Ferreira <a.r.ferreira@gmail.com>
COPYRIGHT AND LICENSE
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.