NAME
JSON::Lines - Parse JSONLines with perl.
VERSION
Version 1.11
SYNOPSIS
use JSON::Lines;
my $jsonl = JSON::Lines->new();
my @data = (
["Name", "Session", "Score", "Completed"],
["Gilbert", "2013", 24, true],
["Alexa", "2013", 29, true],
["May", "2012B", 14, false],
["Deloise", "2012A", 19, true]
);
my $string = $jsonl->encode(@data);
my $file = $jsonl->encode_file('score.jsonl', @data);
# ["Name", "Session", "Score", "Completed"]
# ["Gilbert", "2013", 24, true]
# ["Alexa", "2013", 29, true]
# ["May", "2012B", 14, false]
# ["Deloise", "2012A", 19, true]
...
my $all = $jsonl->decode_file($file);
open my $fh, '<', $file or die $!;
while (my $line = $jsonl->get_line($fh)) {
push @lines, $line;
}
close $fh;
open my $fh, '<', $file or die $!;
my @hundred_lines = $jsonl->get_lines($fh, 100);
close $fh;
...
use JSON::Lines qw/jsonl/;
my $data = [
{
"name" => "Gilbert",
"wins" => [
["straight", "7♣"],
["one pair", "10♥"]
]
},
{
"name" => "Alexa",
"wins" => [
["two pair", "4♠"],
["two pair", "9♠"]
]
},
{
"name" => "May",
"wins" => []
},
{
"name" => "Deloise",
"wins" => [
["three of a kind", "5♣"]
]
}
];
my $string = jsonl( canonical => 1, encode => 1, data => $data );
# {"name": "Gilbert", "wins": [["straight", "7♣"], ["one pair", "10♥"]]}
# {"name": "Alexa", "wins": [["two pair", "4♠"], ["two pair", "9♠"]]}
# {"name": "May", "wins": []}
# {"name": "Deloise", "wins": [["three of a kind", "5♣"]]}
DESCRIPTION
JSON Lines is a convenient format for storing structured data that may be processed one record at a time. It works well with unix-style text processing tools and shell pipelines. It's a great format for log files. It's also a flexible format for passing messages between cooperating processes.
EXPORT
jsonl
my $string = jsonl( success_cb => sub { ... }, error_cb => sub { ... }, encode => 1, data => $aoh );
my $aoa = jsonl( parse_headers => 1, decode => 1, data => $string )
SUBROUTINES/METHODS
new
Instantiate a new JSON::Lines object.
my $jsonl = JSON::Lines->new(
success_cb => sub { if ($_[0] eq 'encode') { ... } },
error_cb => sub { if ($_[0] eq 'decode') { ... } },
canonical => 1,
utf8 => 1,
pretty => 1,
parse_headers => 1
);
success_cb
Callback called on successfull encode or decode of an item.
error_cb
Callback called on unsucessfull encode or decode of an item.
canonical
Print in canonical order.
utf8
utf8 encode/decode
pretty
Pretty print.
parse_headers
Parse the first line of the stream as headers.
All of the above options can also be get/set dynamically via accessor methods:
# Get current value
my $is_pretty = $jsonl->pretty;
# Set value (returns $self for chaining)
$jsonl->pretty(1)->canonical(1);
# Set callbacks
$jsonl->error_cb(sub { warn "Error: $_[1]" });
$jsonl->success_cb(sub { print "Processed: $_[1]" });
encode
Encode a perl struct into a json lines string.
$jsonl->encode( $data );
encode_file
Encode a perl struct into a json lines file.
$jsonl->encode_file($file, $data);
decode
Decode a json lines string into a perl struct. Handles multiple JSON objects per line (e.g., from streaming output that concatenates objects without newlines). The decoder is string-aware, correctly handling unbalanced braces within JSON string values (e.g., code snippets containing { or }).
$jsonl->decode( $string );
# Handles multiple objects on one line:
my @data = $jsonl->decode('{"a":1}{"b":2}');
# Returns: ({ a => 1 }, { b => 2 })
# Handles code in strings:
my @data = $jsonl->decode('{"code":"sub foo { }"}');
# Correctly parses as single object
Supports chunked/streaming input - incomplete JSON is buffered and combined with subsequent calls. Use remaining() to check buffer state and clear_buffer() to reset.
decode_file
Decode a json lines file into a perl struct.
$jsonl->decode_file( $file );
remaining
Returns any incomplete JSON data buffered from previous decode() calls. Useful for debugging chunked input scenarios.
my $buffered = $jsonl->remaining;
if (length $buffered) {
warn "Incomplete JSON in buffer: $buffered";
}
clear_buffer
Clears the internal buffer used for chunked input. Call this to reset state between unrelated decode operations on the same instance.
$jsonl->clear_buffer;
# Fresh state for new input
my @data = $jsonl->decode($new_input);
add_line
Add a new line to the current JSON::Lines stream.
$jsonl->add_line($line);
$jsonl->add_line($line, $fh);
get_line
Decode a json lines file, one object at a time. If a line contains multiple JSON objects, they are buffered and returned one at a time on subsequent calls.
open my $fh, "<", $file or die "$file: $!";
while (my $obj = $jsonl->get_line($fh)) {
print $obj->{id}, "\n";
}
close $fh;
get_lines
Decode a json lines file, 'n' lines at a time.
open my $fh, "<", $file or die "$file: $!";
my @lines = $jsonl->get_lines($fh, 100);
close $fh;
clear_stream
Clear the current JSON::Lines stream.
$jsonl->clear_stream;
get_subset
Get a subset of JSON lines, optionally pass a file to write to.
my $lines = $jsonl->get_subset($file, $offset, $length);
$jsonl->get_subset($file, $offset, $length, $out_file);
get_line_at
Get a single record at a specific index. Supports both plain line numbers and "line:offset" format for accessing multiple objects on the same line.
my $record = $jsonl->get_line_at($fh, 5, 1); # line 5, seek to beginning first
my $record = $jsonl->get_line_at($fh, 5); # line 5, no seek
my $record = $jsonl->get_line_at($fh, '2:1', 1); # line 2, second object on that line
Returns undef if the index is beyond the end of the file. Works with indices returned by group_lines (which may return "line:offset" format for multi-object lines).
group_lines
Group objects in a JSONL file by a key value, returning a hash of indices. For lines with multiple objects, indices use "line:offset" format (e.g., "0:1" for the second object on line 0). Single-object lines use plain integers.
open my $fh, '<', $file or die $!;
my $groups = $jsonl->group_lines($fh, 'category');
# Returns: { 'cat1' => [0, '2:0', '2:1'], 'cat2' => [1, '3:0'] }
# With a coderef for complex grouping:
my $groups = $jsonl->group_lines($fh, sub { $_->{nested}{key} });
close $fh;
# Use returned indices with get_line_at:
for my $idx (@{$groups->{cat1}}) {
my $obj = $jsonl->get_line_at($fh, $idx, !$first++);
}
The returned indices are compatible with get_line_at.
AUTHOR
LNATION, <thisusedtobeanemail at gmail.com>
BUGS
Please report any bugs or feature requests to bug-json-lines at rt.cpan.org, or through the web interface at https://rt.cpan.org/NoAuth/ReportBug.html?Queue=JSON-Lines. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
SUPPORT
You can find documentation for this module with the perldoc command.
perldoc JSON::Lines
You can also look for information at:
RT: CPAN's request tracker (report bugs here)
Search CPAN
ACKNOWLEDGEMENTS
LICENSE AND COPYRIGHT
This software is Copyright (c) 2020->2025 by LNATION.
This is free software, licensed under:
The Artistic License 2.0 (GPL Compatible)