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) ;
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"
}
Example 2 - Packing
Traditional pretty-printing:
{
"states": [
"Alabama",
"Alaska",
"Arizona",
...
"Wyoming"
]
}
JSONFold:
{
"states": [
"Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado",
"Connecticut", "Delaware", "Florida", "Georgia", ...
"West_Virginia", "Wisconsin", "Wyoming"
]
}
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
}
]
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 }
]
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
JSONandJSON::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)