File Coverage

blib/lib/Mojo/JSON/MaybeXS.pm
Criterion Covered Total %
statement 19 19 100.0
branch n/a
condition n/a
subroutine 9 9 100.0
pod n/a
total 28 28 100.0


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