CPANPLUS
view release on metacpan or search on metacpan
inc/bundle/JSON/PP.pm view on Meta::CPAN
my %ORDER = (id => 1, class => 2, name => 3);
$json->sort_by(sub {
($ORDER{$JSON::PP::a} // 999) <=> ($ORDER{$JSON::PP::b} // 999)
or $JSON::PP::a cmp $JSON::PP::b
});
print $json->encode([
{name => 'CPAN', id => 1, href => 'http://cpan.org'}
]);
# [{"id":1,"name":"CPAN","href":"http://cpan.org"}]
Note that C<sort_by> affects all the plain hashes in the data structure.
If you need finer control, C<tie> necessary hashes with a module that
implements ordered hash (such as L<Hash::Ordered> and L<Tie::IxHash>).
C<canonical> and C<sort_by> don't affect the key order in C<tie>d
hashes.
use Hash::Ordered;
tie my %hash, 'Hash::Ordered',
(name => 'CPAN', id => 1, href => 'http://cpan.org');
print $json->encode([\%hash]);
# [{"name":"CPAN","id":1,"href":"http://cpan.org"}] # order is kept
=head1 INCREMENTAL PARSING
This section is also taken from JSON::XS.
In some cases, there is the need for incremental parsing of JSON
texts. While this module always has to keep both JSON text and resulting
Perl data structure in memory at one time, it does allow you to parse a
JSON stream incrementally. It does so by accumulating text until it has
a full JSON object, which it then can decode. This process is similar to
using C<decode_prefix> to see if a full JSON object is available, but
is much more efficient (and can be implemented with a minimum of method
calls).
JSON::PP will only attempt to parse the JSON text once it is sure it
has enough text to get a decisive result, using a very simple but
truly incremental parser. This means that it sometimes won't stop as
early as the full parser, for example, it doesn't detect mismatched
parentheses. The only thing it guarantees is that it starts decoding as
soon as a syntactically valid JSON text has been seen. This means you need
to set resource limits (e.g. C<max_size>) to ensure the parser will stop
parsing in the presence if syntax errors.
The following methods implement this incremental parser.
=head2 incr_parse
$json->incr_parse( [$string] ) # void context
$obj_or_undef = $json->incr_parse( [$string] ) # scalar context
@obj_or_empty = $json->incr_parse( [$string] ) # list context
This is the central parsing function. It can both append new text and
extract objects from the stream accumulated so far (both of these
functions are optional).
If C<$string> is given, then this string is appended to the already
existing JSON fragment stored in the C<$json> object.
After that, if the function is called in void context, it will simply
return without doing anything further. This can be used to add more text
in as many chunks as you want.
If the method is called in scalar context, then it will try to extract
exactly I<one> JSON object. If that is successful, it will return this
object, otherwise it will return C<undef>. If there is a parse error,
this method will croak just as C<decode> would do (one can then use
C<incr_skip> to skip the erroneous part). This is the most common way of
using the method.
And finally, in list context, it will try to extract as many objects
from the stream as it can find and return them, or the empty list
otherwise. For this to work, there must be no separators (other than
whitespace) between the JSON objects or arrays, instead they must be
concatenated back-to-back. If an error occurs, an exception will be
raised as in the scalar context case. Note that in this case, any
previously-parsed JSON texts will be lost.
Example: Parse some JSON arrays/objects in a given string and return
them.
my @objs = JSON::PP->new->incr_parse ("[5][7][1,2]");
=head2 incr_text
$lvalue_string = $json->incr_text
This method returns the currently stored JSON fragment as an lvalue, that
is, you can manipulate it. This I<only> works when a preceding call to
C<incr_parse> in I<scalar context> successfully returned an object. Under
all other circumstances you must not call this function (I mean it.
although in simple tests it might actually work, it I<will> fail under
real world conditions). As a special exception, you can also call this
method before having parsed anything.
That means you can only use this function to look at or manipulate text
before or after complete JSON objects, not while the parser is in the
middle of parsing a JSON object.
This function is useful in two cases: a) finding the trailing text after a
JSON object or b) parsing multiple JSON objects separated by non-JSON text
(such as commas).
=head2 incr_skip
$json->incr_skip
This will reset the state of the incremental parser and will remove
the parsed text from the input buffer so far. This is useful after
C<incr_parse> died, in which case the input buffer and incremental parser
state is left unchanged, to skip the text parsed so far and to reset the
parse state.
The difference to C<incr_reset> is that only text until the parse error
occurred is removed.
=head2 incr_reset
$json->incr_reset
This completely resets the incremental parser, that is, after this call,
it will be as if the parser had never parsed anything.
This is useful if you want to repeatedly parse JSON objects and want to
ignore any trailing data, which means you have to reset the parser after
each successful decode.
=head1 MAPPING
Most of this section is also taken from JSON::XS.
This section describes how JSON::PP maps Perl values to JSON values and
vice versa. These mappings are designed to "do the right thing" in most
circumstances automatically, preserving round-tripping characteristics
(what you put in comes out as something equivalent).
For the more enlightened: note that in the following descriptions,
lowercase I<perl> refers to the Perl interpreter, while uppercase I<Perl>
refers to the abstract Perl language itself.
=head2 JSON -> PERL
=over 4
=item object
A JSON object becomes a reference to a hash in Perl. No ordering of object
keys is preserved (JSON does not preserve object key ordering itself).
( run in 1.440 second using v1.01-cache-2.11-cpan-364913b4093 )