line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Mojo::JSON::MaybeXS; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
94614
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
41
|
|
4
|
1
|
|
|
1
|
|
7
|
use warnings; |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
41
|
|
5
|
1
|
|
|
1
|
|
516
|
use Mojo::Util 'monkey_patch'; |
|
1
|
|
|
|
|
146126
|
|
|
1
|
|
|
|
|
127
|
|
6
|
1
|
|
|
1
|
|
461
|
use JSON::MaybeXS 'JSON'; |
|
1
|
|
|
|
|
4097
|
|
|
1
|
|
|
|
|
47
|
|
7
|
1
|
|
|
1
|
|
259
|
use Mojo::JSON (); |
|
1
|
|
|
|
|
13112
|
|
|
1
|
|
|
|
|
265
|
|
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
our $VERSION = '1.000'; |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
my $BINARY = JSON::MaybeXS->new(utf8 => 1, canonical => 1, allow_nonref => 1, |
12
|
|
|
|
|
|
|
allow_unknown => 1, allow_blessed => 1, convert_blessed => 1); |
13
|
|
|
|
|
|
|
my $TEXT = JSON::MaybeXS->new(utf8 => 0, canonical => 1, allow_nonref => 1, |
14
|
|
|
|
|
|
|
allow_unknown => 1, allow_blessed => 1, convert_blessed => 1); |
15
|
|
|
|
|
|
|
my $TRUE = JSON->true; |
16
|
|
|
|
|
|
|
my $FALSE = JSON->false; |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
if (JSON eq 'Cpanel::JSON::XS') { |
19
|
|
|
|
|
|
|
local $@; |
20
|
|
|
|
|
|
|
if (eval { Cpanel::JSON::XS->VERSION('3.0112'); 1 }) { |
21
|
|
|
|
|
|
|
$BINARY->stringify_infnan; |
22
|
|
|
|
|
|
|
$TEXT->stringify_infnan; |
23
|
|
|
|
|
|
|
} |
24
|
|
|
|
|
|
|
if (eval { Cpanel::JSON::XS->VERSION('3.0206'); 1 }) { |
25
|
|
|
|
|
|
|
$BINARY->escape_slash; |
26
|
|
|
|
|
|
|
$TEXT->escape_slash; |
27
|
|
|
|
|
|
|
} |
28
|
|
|
|
|
|
|
} elsif (JSON eq 'JSON::PP') { |
29
|
|
|
|
|
|
|
$BINARY->escape_slash; |
30
|
|
|
|
|
|
|
$TEXT->escape_slash; |
31
|
|
|
|
|
|
|
} |
32
|
|
|
|
|
|
|
|
33
|
61
|
|
|
61
|
|
33696
|
monkey_patch 'Mojo::JSON', 'encode_json', sub { $BINARY->encode($_[0]) }; |
34
|
68
|
|
|
68
|
|
41786
|
monkey_patch 'Mojo::JSON', 'decode_json', sub { $BINARY->decode($_[0]) }; |
35
|
|
|
|
|
|
|
|
36
|
2
|
|
|
2
|
|
22
|
monkey_patch 'Mojo::JSON', 'to_json', sub { $TEXT->encode($_[0]) }; |
37
|
3
|
|
|
3
|
|
1085
|
monkey_patch 'Mojo::JSON', 'from_json', sub { $TEXT->decode($_[0]) }; |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
monkey_patch 'Mojo::JSON', 'true', sub () { $TRUE }; |
40
|
|
|
|
|
|
|
monkey_patch 'Mojo::JSON', 'false', sub () { $FALSE }; |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
1; |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
=head1 NAME |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
Mojo::JSON::MaybeXS - use JSON::MaybeXS as the JSON encoder for Mojolicious |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
=head1 SYNOPSIS |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
use Mojo::JSON::MaybeXS; |
51
|
|
|
|
|
|
|
use Mojo::JSON qw/encode_json decode_json true false/; |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
# Preload for scripts using Mojo::JSON |
54
|
|
|
|
|
|
|
$ perl -MMojo::JSON::MaybeXS -S morbo myapp.pl |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
# Must be set in environment for hypnotoad |
57
|
|
|
|
|
|
|
$ PERL5OPT=-MMojo::JSON::MaybeXS hypnotoad myapp.pl |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
=head1 DESCRIPTION |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
L is a monkey-patch module for using L as |
62
|
|
|
|
|
|
|
the JSON encoder for a L application, or anything else using |
63
|
|
|
|
|
|
|
L. It must be loaded before L so the new functions will |
64
|
|
|
|
|
|
|
be properly exported. |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
=head1 CAVEATS |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
L may load different modules behind the scenes depending on what |
69
|
|
|
|
|
|
|
is available, and these modules have slightly different behavior from |
70
|
|
|
|
|
|
|
L and occasionally from each other. References to the behavior of |
71
|
|
|
|
|
|
|
L below are actually describing the behavior shared among the |
72
|
|
|
|
|
|
|
modules it loads. |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
L is used with the options C, C, |
75
|
|
|
|
|
|
|
C, C, and C. C |
76
|
|
|
|
|
|
|
enables sorting of hash keys when encoding to JSON objects as L |
77
|
|
|
|
|
|
|
does. C allows encoding and decoding of bare values outside of |
78
|
|
|
|
|
|
|
hash/array references, since L does not prevent this, in accordance |
79
|
|
|
|
|
|
|
with L. The other options prevent |
80
|
|
|
|
|
|
|
the encoder from blowing up when encountering values that cannot be represented |
81
|
|
|
|
|
|
|
in JSON to better match the behavior of L; in most cases, where |
82
|
|
|
|
|
|
|
L would stringify a reference, L with these settings |
83
|
|
|
|
|
|
|
will encode it to C. See below for more specifics. |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
To better match the behavior of L, certain options may be enabled |
86
|
|
|
|
|
|
|
depending on the backend that is used. If L version 3.0112 or |
87
|
|
|
|
|
|
|
greater is loaded, it will be used with the option C. If |
88
|
|
|
|
|
|
|
either L of at least version 3.0206 or L is loaded, |
89
|
|
|
|
|
|
|
it will be used with the option C. |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
As of this writing, the author has found the following incompatibilities: |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
=head2 Object Conversion |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
Both L and L will attempt to call the TO_JSON method |
96
|
|
|
|
|
|
|
of a blessed reference to produce a JSON-friendly structure. If that method |
97
|
|
|
|
|
|
|
does not exist, L or L version 3.0207 or greater |
98
|
|
|
|
|
|
|
will stringify the object, while L or L will always encode |
99
|
|
|
|
|
|
|
it to C. |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
print encode_json([DateTime->now]); |
102
|
|
|
|
|
|
|
# Mojo::JSON or Cpanel::JSON::XS >= 3.0207: ["2014-11-30T04:31:13"] |
103
|
|
|
|
|
|
|
# JSON::XS or JSON::PP: [null] |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
=head2 Unblessed References |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
L does not allow unblessed references other than to hashes, |
108
|
|
|
|
|
|
|
arrays, or the scalar values C<0> and C<1>, and will encode them to C. |
109
|
|
|
|
|
|
|
L will treat all scalar references the same as references to C<0> |
110
|
|
|
|
|
|
|
or C<1> and will encode them to C or C depending on their boolean |
111
|
|
|
|
|
|
|
value. Other references (code, filehandle, etc) will be stringified. |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
print encode_json([\'asdf', sub { 1 }]); |
114
|
|
|
|
|
|
|
# Mojo::JSON: [true,"CODE(0x11d1650)"] |
115
|
|
|
|
|
|
|
# JSON::MaybeXS: [null,null] |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
=head2 Escapes |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
L currently escapes the slash character C> for security reasons, |
120
|
|
|
|
|
|
|
as well as the unicode characters C and C. L |
121
|
|
|
|
|
|
|
version 3.0206 or greater and L will have the option set to escape |
122
|
|
|
|
|
|
|
the slash character, and L does not escape these characters. This |
123
|
|
|
|
|
|
|
does not affect decoding of the resulting JSON. |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
print encode_json(["/\x{2028}/\x{2029}"]); |
126
|
|
|
|
|
|
|
# Mojo::JSON: ["\/\u2028\/\u2029"] |
127
|
|
|
|
|
|
|
# Cpanel::JSON::XS >= 3.0206 or JSON::PP: ["\/ \/ "] |
128
|
|
|
|
|
|
|
# JSON::XS: ["/ / "] |
129
|
|
|
|
|
|
|
# Both decode to arrayref containing: "/\x{2028}/\x{2029}" |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
=head2 inf and nan |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
L encodes C and C to strings. L version |
134
|
|
|
|
|
|
|
3.0112 or greater will also stringify C and C. However, L |
135
|
|
|
|
|
|
|
or L will encode them as numbers (barewords) producing invalid JSON. |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
print encode_json([9**9**9, -sin 9**9**9]); |
138
|
|
|
|
|
|
|
# Mojo::JSON or Cpanel::JSON::XS >= 3.0112: ["inf","nan"] (on Linux) |
139
|
|
|
|
|
|
|
# JSON::XS or JSON::PP: [inf,nan] |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
=head2 Upgraded Numbers |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
L, if using L or L, will attempt to guess if |
144
|
|
|
|
|
|
|
a value to be encoded is numeric or string based on its last usage. Therefore, |
145
|
|
|
|
|
|
|
using a variable containing C<13> in a string will cause it to be encoded as |
146
|
|
|
|
|
|
|
C<"13"> even if the variable itself was not changed. L or |
147
|
|
|
|
|
|
|
L version 3.0109 or greater will encode C<13> as C<13> |
148
|
|
|
|
|
|
|
regardless of whether it has been used as a string. |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
my ($num1, $num2) = (13, 14); |
151
|
|
|
|
|
|
|
my $str = "$num1"; |
152
|
|
|
|
|
|
|
print encode_json([$num1, $num2, $str]); |
153
|
|
|
|
|
|
|
# Mojo::JSON or Cpanel::JSON::XS >= 3.0109: [13,14,"13"] |
154
|
|
|
|
|
|
|
# JSON::XS or JSON::PP: ["13",14,"13"] |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
=head2 Duplicate Keys |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
L, L, and L will silently accept duplicate keys |
159
|
|
|
|
|
|
|
in the same JSON object when decoding a JSON string. L |
160
|
|
|
|
|
|
|
version 3.0235 or greater will throw an exception if duplicate keys are |
161
|
|
|
|
|
|
|
encountered. |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
print dumper decode_json('{"foo":1, "bar":2, "foo":3}'); |
164
|
|
|
|
|
|
|
# Mojo::JSON, JSON::XS, or JSON::PP: { bar => 2, foo => 3 } |
165
|
|
|
|
|
|
|
# Cpanel::JSON::XS >= 3.0235: "Duplicate keys not allowed" exception |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
=head1 BUGS |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
This is a monkey-patch of one of a few possible modules into another, and they |
170
|
|
|
|
|
|
|
have incompatibilities, so there will probably be bugs. Report any issues on |
171
|
|
|
|
|
|
|
the public bugtracker. |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
=head1 AUTHOR |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
Dan Book, C |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
=head1 CREDITS |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
Sebastian Riedel, author of L, for basic implementation. |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
Copyright 2014, Dan Book. |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
This library is free software; you may redistribute it and/or modify it under |
186
|
|
|
|
|
|
|
the terms of the Artistic License version 2.0. |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
=head1 SEE ALSO |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
L, L, L, L, L |