I'm using the read_file
sub from the File::Slurp
module and the decode_json
sub from the JSON
module to easily read the contents of a file for JSON decoding. However, I found that when my file contains newlines, I can't directly pass the return value of read_file
to decode_json
, as I receive an error regarding invalid JSON. Instead, I have to store the return value of read_file
into a variable before passing it.
I'm still pretty new to Perl (using v5.30 or v5.38 depending on system), and coming from languages like JS and Python this surprises me; why is this intermediate variable assignment required? Not that this isn't an easy enough workaround, just looking to satisfy my curiosity.
Example:
use v5.38;
use warnings;
use strict;
use File::Slurp qw( read_file );
use JSON qw( decode_json );
my $contents = read_file('test.json');
my $decoded = decode_json($contents);
say "Decoded contents";
my $chained_decoded = decode_json( read_file('test.json') );
say "Decoded chained contents";
Alongside a file test.json
with the contents:
[{ "a": "b" }, { "b": "c" }]
This causes no errors, and both logs show up.
However, with the contents:
[
{ "a": "b" },
{ "b": "c" }
]
I see the first log, but then the error , or ] expected while parsing array, at character offset 2 (before "(end of string)") at test.pl line 12.
is thrown
read_file
is documented as being context-sensitive: in scalar context it returns the entire contents of the file as one string. In list context it returns a list of lines.
The arguments list of a function call is a list context, but decode_json
doesn't want a list of lines, it wants the whole file in the first argument and ignores the rest.
You can force scalar context by writing decode_json(scalar read_file('test.json'))
.