Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the JSON module quote some numbers but not others?

Tags:

json

perl

We recently switched to the new JSON2 perl module. I thought all and everything gets returned quoted now. But i encountered some cases in which a number (250) got returned as unquoted number in the json string created by perl.

Out of curiosity: Does anyone know why such cases exist and how the json module decides if to quote a value?

like image 598
Thariama Avatar asked Jan 14 '23 04:01

Thariama


2 Answers

It will be unquoted if it's a number. Without getting too deeply into Perl internals, something is a number if it's a literal number or the result of an arithmetic operation, and it hasn't been stringified since its numeric value was produced.

use JSON::XS;
my $json = JSON::XS->new->allow_nonref;

say $json->encode(42);   # 42
say $json->encode("42"); # "42"

my $x = 4;
say $json->encode($x); # 4
my $y = "There are $x lights!";
say $json->encode($x); # "4"
$x++; # modifies the numeric value of $x
say $json->encode($x); # 5

Note that printing a number isn't "stringifying it" even though it produces a string representation of the number to output; print $x doesn't cause a number to be a string, but print "$x" does.

Anyway, all of this is a bit weird, but if you want a value to be reliably unquoted in JSON then put 0 + $value into your structure immediately before encoding it, and if you want it to be reliably quoted then use "" . $value or "$value".

like image 66
hobbs Avatar answered Feb 24 '23 13:02

hobbs


You can force it into a string by doing something like this:

$number_str = '' . $number;

For example:

perl -MJSON -le 'print encode_json({foo=>123, bar=>"".123})'
{"bar":"123","foo":123}

It looks like older versions of JSON has autoconvert functionality that can be set. Did you not have $JSON::AUTOCONVERT set to a true value?

like image 30
gpojd Avatar answered Feb 24 '23 14:02

gpojd