DEV Community

Cover image for JSON::JSONFold – a CPAN module for compact, readable JSON formatting
Yair Lenga
Yair Lenga

Posted on • Originally published at Medium

JSON::JSONFold – a CPAN module for compact, readable JSON formatting

I've been working on a CPAN module called JSON::JSONFold, and I wrote an article describing the motivation and design. I'd really appreciate feedback from other Perl developers.

JSON serializers tend to give us two choices: compact JSON, which is efficient but a dense wall of text that's painful to read, or pretty-printed JSON, which is readable but often wastes a lot of vertical space (a small array of numbers can turn into ten lines).

I wanted something in between. JSONFold keeps the shape of pretty-printed JSON, but folds small, simple structures back onto a single line whenever that improves readability. It works on top of your existing serializer (JSON, JSON::PP, JSON::XS, etc.) - you keep using whatever you already have, and JSONFold just reformats the output.

Example 1 - Coding

use JSON::JSONFold qw(encode_json);

my $data = {
    _id       => 123,
    locations => [
      { city => "Boston",    state => "MA", country => "USA" },
      { city => "Seattle",   state => "WA", country => "USA" },
      { city => "Montreal",  state => "QC", country => "Canada" },
    ],
    info      => {
      roles     => [ "foo", "bar", "baz" ],
    },
    name      => "Alice",
};

print encode_json($data) ;
Enter fullscreen mode Exit fullscreen mode

Output

{
  "_id": 123,
  "info": { "roles": [ "foo", "bar", "baz" ] },
  "locations": [
    { "city": "Boston",   "country": "USA",    "state": "MA" },
    { "city": "Seattle",  "country": "USA",    "state": "WA" },
    { "city": "Montreal", "country": "Canada", "state": "QC" }
  ],
  "name": "Alice"
}
Enter fullscreen mode Exit fullscreen mode

Example 2 - Packing

Traditional pretty-printing:

{
  "states": [
    "Alabama",
    "Alaska",
    "Arizona",
    ...
    "Wyoming"
  ]
}
Enter fullscreen mode Exit fullscreen mode

JSONFold:

{
  "states": [
    "Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado",
    "Connecticut", "Delaware", "Florida", "Georgia", ...
    "West_Virginia", "Wisconsin", "Wyoming"
  ]
}
Enter fullscreen mode Exit fullscreen mode

Same data, just using the available line width more effectively.

Example 3 - Grid Formatting

When an array contains repeated structures, JSONFold can align values into columns:

Traditional pretty-printing:

[
  {
    "orders": 18,
    "product": "Laptop",
    "region": "North",
    "sales": 1250
  },
  ...
  {
    "orders": 24,
    "product": "Mouse",
    "region": "East",
    "sales": 1422
  }
]
Enter fullscreen mode Exit fullscreen mode

JSONFold:

[
  { "orders": 18, "product": "Laptop",   "region": "North",     "sales": 1250 },
  { "orders": 21, "product": "Monitor",  "region": "Southwest", "sales": 1345 },
  { "orders": 17, "product": "Keyboard", "region": "West",      "sales": 1198 },
  { "orders": 24, "product": "Mouse",    "region": "East",      "sales": 1422 }
]
Enter fullscreen mode Exit fullscreen mode

The module also supports:

  • Folding small arrays and objects onto a single line.
  • Joining adjacent folded objects to further reduce vertical space.
  • Compatibility APIs similar to JSON and JSON::PP.

I wrote a more detailed article covering the design, implementation, and full set of examples:

Medium: https://medium.com/p/a619c9e7c3ec

CPAN: https://metacpan.org/pod/JSON::JSONFold

GitHub: https://github.com/yairlenga/jsonfold/tree/main/perl

I'd love to hear what the Perl community thinks. Has anyone else run into JSON pretty-printing pain in logs, configs, or debugging output? And are there formatting styles or options you'd want to see?

Top comments (0)