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