JSON::PP::Monkey - aferreira/cpan-JSON-PP-Monkey GitHub Wiki
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.
# { "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 applied -
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).
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).
Defaults to disabled.
$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.
$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.
$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.
$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.
$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
$json = $json->remove_fallback($case, $cb);