JSON (JavaScript Object Notation) is a lightweight data interchange (serialization) format inspired by JavaScript object literal syntax.

examples/sample.json

{
   "YAML" : "YAML Ain't Markup Language",
   "Languages" : [
      "perl",
      "python",
      "javascript"
   ]
}

JSON implementations in Perl

There are several modules that can convert Perl data structures to JSON, and JSON to Perl data structures.

JSON::PP is a Pure-Perl implementation that can be found in the recent releases of Perl core. According to comments on this article Mojo::JSON, which is also a pure-Perl implementation, is 50% faster than JSON::PP.

According to my measurements Cpanel::JSON::XS is the fastest implementation and despite its name, the only connection to Cpanel is that they sponsor the maintenance of it.

JSON::MaybeXS is a wrapper around a number of these implementations. It will use the XS (and therefore much faster) version if it is installed, and will use the Pure-Perl version if the XS version is not installed.

There are plenty of other modules on CPAN handling JSON in various special cases. If you know about another one you think should be mentioned here, please send a note or a pull-request.

Usage example: Encoding Perl to JSON

Let's say we have a data structure in Perl - a reference of a HASH with an internal array, and internal hash, and one of the keys, 'gender', without a value. Having no value is represented with undef in Perl.

my $student = {
    name => 'Foo Bar',
    email => 'foo@bar.com',
    gender => undef,
    classes => [
        'Chemistry',
        'Math',
        'Literature',
    ],
    address => {
        city => 'Fooville',
        planet => 'Earth',
    },
};

We can use the encode_json function exported by the Cpanel::JSON::XS module to convert this data structure to a JSON string:

examples/json_encode.pl

use strict;
use warnings;
use 5.010;

use JSON::MaybeXS qw(encode_json decode_json);

my $student = {
    name => 'Foo Bar',
    email => 'foo@bar.com',
    gender => undef,
    classes => [
        'Chemistry',
        'Math',
        'Litreture',
    ],
    address => {
        city => 'Fooville',
        planet => 'Earth',
    },
};

my $student_json = encode_json $student;
say $student_json;

The resulting output looks like this:

{"classes":["Chemistry","Math","Literature"],"gender":null,"name":"Foo Bar","email":"foo@bar.com","address":{"city":"Fooville","planet":"Earth"}}

Even without knowing JavaScript, you can see that it is quite similar to what we had in Perl, though this is a compact version of the JSON string and thus there are no linebreaks. Still we can see that instead of the => we used for representing key-value pairs, here we have :, and instead of the undef, here we have null. Oh and the keys are all inside double-quotes.

We can now take this string, save it to file or send it to another computer.

Encoding JSON in a human-readable way

While the above JSON is compact, it is also quite difficult to read and manually edit. We can ask the JSON encoder to make the JSON pretty. (Sometimes this is called JSON beautification or JSON beautifier). The syntax is slightly different:

examples/json_encode_pretty.pl

use strict;
use warnings;
use 5.010;

use JSON::MaybeXS ();

my $student = {
    name => 'Foo Bar',
    email => 'foo@bar.com',
    gender => undef,
    classes => [
        'Chemistry',
        'Math',
        'Litreture',
    ],
    address => {
        city => 'Fooville',
        planet => 'Earth',
    },
};

my $json = JSON::MaybeXS->new(utf8 => 1, pretty => 1, sort_by => 1);
my $student_json = $json->encode($student);
say $student_json;


(You might need a relatively recent version of Cpanel::JSON::XS to support the sort_by parameter.

$ perl examples/json_encode_pretty.pl

So is the result:

{
   "address" : {
      "city" : "Fooville",
      "planet" : "Earth"
   },
   "classes" : [
      "Chemistry",
      "Math",
      "Litreture"
   ],
   "email" : "foo@bar.com",
   "gender" : null,
   "name" : "Foo Bar"
}

Decoding JSON to Perl

In the other way around, let's assume we have a JSON string in the $student_json variable. We can use the decode_json function exported by the Cpanel::JSON::XS module to convert this string to a Perl data structure and then we use Data::Dumper to print out a more familiar representation of the data.

examples/json_decode.pl

use strict;
use warnings;
use 5.010;

use JSON::MaybeXS qw(encode_json decode_json);

my $student_json = '{"classes":["Chemistry","Math","Litreture"],"gender":null,"name":"Foo Bar","email":"foo@bar.com","address":{"city":"Fooville","planet":"Earth"}}';

my $student = decode_json $student_json;

use Data::Dumper;
print Dumper $student;

The output will look like this though of course the order of the keys might be different. After all Perl does not maintain order among the hash keys.

$VAR1 = {
          'gender' => undef,
          'email' => 'foo@bar.com',
          'address' => {
                         'planet' => 'Earth',
                         'city' => 'Fooville'
                       },
          'classes' => [
                         'Chemistry',
                         'Math',
                         'Literature'
                       ],
          'name' => 'Foo Bar'
        };

From these two examples it is quite easy to construct a round-trip example, that encodes a Perl data structure to JSON and then decodes the string back. Of course that's not very interesting in itself. It would be much more interesting to also save the file to the disk in the middle. Further down you'll find an exercise that will do that.

More about JSON

Of course the above was just a taste into how the encoding/decoding works. There are quite a few issues you might need to be aware, probably the most important is how the encoding handles blessed Perl objects.

Exercise

As an exercise, let's create a script that acts as a counter. It will accept a string on the command line, increase a counter and display that value. Each string will have its own counter. It would work like this:

$ count foo
  foo: 1
$ count foo
  foo: 2
$ count bar
  bar: 1
$ count foo
  foo: 3

Other languages

PHP has built-in functions such as json_decode and json_encode.

Python comes with a class called json that will handle all aspects of JSON processing.

Ruby also comes with a standard library handling JSON files