=encoding UTF-8

=head1 NAME

JSON::Create - turn a Perl variable into JSON

=head1 SYNOPSIS

    use JSON::Create 'create_json';
    my %hash = (a => b, c => d);
    my $json = create_json (\%hash);
    # Now $json contains '{"a":"b","c":"d"}', or similar.

=head1 DESCRIPTION

This module produces JSON out of Perl for the simple cases of strings,
numbers, nested hashes and arrays.

=head1 FUNCTIONS

=head2 create_json

    my $json = create_json (\%hash);

Convert a Perl hash or array into JSON.

=head1 CONVERSIONS

This section details what conversions are applied to the various
inputs to produce outputs.

=head2 Hashes

Associative arrays are converted to JSON objects. The keys are written
into JSON as strings, with any control characters escaped. The order
of the keys is as they are supplied by Perl.

=head2 Arrays

Arrays are converted to JSON arrays. The order of the array is
identical to the Perl one.

=head2 Scalars

Non-reference scalars are converted to strings, JSON integers or JSON
floats depending on what Perl says they contain.

=head3 Strings

As far as possible, strings are written as-is to the JSON.  See
L</RFC 7159> for details of JSON's rules for strings.

Bytes of value less than 0x20 are converted into the appropriate JSON
escapes, either the whitespace escapes \b (backspace) \r, \t, \n, and
\f, or the form \u0001 for other control characters. The backslash is
written as \\ and double quotes are written as \". The forward slash,
/, is not escaped. Unicode values are not escaped.

=head3 Integers

Integers are printed in the obvious way. Note that what you input to
Perl as an integer, Perl may interpret to be a floating point number.

=head3 Floating point numbers

Finite floating point numbers are printed using printf formatting via
C<"%g">. 

NaN (not a number) is converted to the string C<"nan">, the letters
C<nan> surrounded by double quotes. Similarly, positive and negative
infinity are converted to the strings C<"inf"> and C<"-inf">
respectively. Note that JSON does not allow these as bare values. See
L</RFC 7159> for details.

=head3 The undefined value

Undefined values are mapped to the JSON literal "null".

=head3 Booleans

There is no way to produce booleans (JSON "true" and "false"
literals).

=head3 Unicode escapes

There is currently no facility to produce Unicode escapes, except for
control characters (bytes less than 0x20 in value which are not
whitespace or \b).

=head3 Unicode

If any part of the input object is marked as "utf8" (multibyte
characters), every non-ASCII string in the input object needs to be
marked as such, otherwise the module prints a warning and returns an
undefined value. If every part of the input is not marked as "utf8",
this does not happen, but there is also currently no validation of the
output as being in Unicode, so binary strings can pass through without
correction. See also L</BUGS>.

=head3 Perl objects

Perl objects are stringified as if via Perl's function "print". For
example

    #!/home/ben/software/install/bin/perl
    use warnings;
    use strict;
    package Ba::Bi::Bu::Be::Bo;
    sub new { my $lion = 'lion'; return bless \$lion; }
    1;
    package main;
    use JSON::Create 'create_json';
    my $babibubebo = Ba::Bi::Bu::Be::Bo->new ();
    print "$babibubebo\n";
    my $stuff = { babibubebo => $babibubebo };
    print create_json ($stuff), "\n";


produces

    Ba::Bi::Bu::Be::Bo=SCALAR(0x288de850)
    {"babibubebo":"Ba::Bi::Bu::Be::Bo=SCALAR(0x288de850)"}

=head2 Regexes

If the scalar contains a regex then JSON::Create lets Perl convert the
regex to a string then adds that. The output depends on the Perl
version.

=head2 Code references and other

A code reference in the input causes the entire return value to be the
undefined value.

=head1 EXPORTS

The module exports nothing except by request. One function,
L</create_json>, is exported on request.

=head1 SEE ALSO

=over

=item RFC 7159

JSON is specified in L<RFC 7159 "The application/json Media Type for
JavaScript Object Notation
(JSON)"|http://www.ietf.org/rfc/rfc7159.txt>.

=item json.org

L<http://json.org> is the website for JSON, authored by Douglas
Crockford.

=item JSON::Parse

This module is a companion module to the same author's
L<JSON::Parse>. Please see that module's documentation for links to
the JSON standard itself, a summary of the ever-growing list of JSON
modules on CPAN (under "SEE ALSO") and the reasons why I decided to
write these two modules (under "HISTORY").

=back

=head1 BUGS

JSON is required to be in Unicode, but it's possible to pass
non-Unicode strings through this module by switching off the Perl
UTF-8 flag everywhere, since unmarked binary bytes are currently not
validated independent of Perl's validation, which does not apply to
unmarked strings.

=head1 PERFORMANCE

This module is currently at an early stage of development, so speed is
not a key issue until the module is demonstrably producing correct
outputs.

However, due to user interest, there is a benchmarking script in
F<bench/bench.pl> which compares the performance of the module with
L<JSON::XS> and L<Cpanel::JSON::XS>. Outputs look like this:

    
    Comparing hash of ASCII strings...
    
            Rate  CJX   JX   JC
    CJX 403150/s   --  -1% -44%
    JX  406349/s   1%   -- -44%
    JC  721127/s  79%  77%   --
    
    Comparing hash of integers...
    
            Rate  CJX   JX   JC
    CJX 163578/s   --  -2% -58%
    JX  167320/s   2%   -- -57%
    JC  387879/s 137% 132%   --
    
    Comparing hash of Unicode strings...
    
            Rate  CJX   JX   JC
    CJX 469725/s   --  -2% -49%
    JX  478505/s   2%   -- -48%
    JC  914286/s  95%  91%   --


This only compares a few simple cases in which the output is
correct. At the moment, this module doesn't handle Perl objects beyond
the default stringification, or produce booleans, but adding these
functionalities should have little to no effect on the above
performance.

=head1 HISTORY

I started making this module so that, with this and JSON::Parse, I
wouldn't have to ever use any of the existing JSON modules on CPAN
ever again. See also L</SEE ALSO> and the HISTORY section of the
documentation of L<JSON::Parse>.

The exact time I've spent making this module is recorded in the file
F<timesheet.txt> in the top directory of the distribution. At the time
of version 0.04_02, I've spent 17 hours and 0 minutes working on
this.

=cut


=head1 AUTHOR

Ben Bullock, <bkb@cpan.org>

=head1 COPYRIGHT & LICENCE

This package and associated files are copyright (C) 
2015
Ben Bullock.

You can use, copy, modify and redistribute this package and associated
files under the Perl Artistic Licence or the GNU General Public
Licence.


=head1 TERMINOLOGY

This defines the terminology used in this document.

=over

=item Convenience function

In this document, a "convenience function" indicates a function which
solves some of the problems, some of the time, for some of the people,
but which may not be good enough for all envisaged uses. A convenience
function is an 80/20 solution, something which solves (about) 80% of
the problems with 20% of the effort. Something which does the obvious
things, but may not do all the things you might want, a time-saver for
the most basic usage cases.

=item BUGS

In this document, the section BUGS describes possible deficiencies,
problems, and workarounds with the module. It's not a guide to bug
reporting, or even a list of actual bugs. The name "BUGS" is the
traditional name for this sort of section in a Unix manual page.

=back


