How to handle JSON boolean values true and false in Perl?
Question
How to handle JSON boolean values true and false in Perl?
Handling JSON boolean values true and false in Perl commonly arises when serializing and deserializing data. The challenge is that JSON booleans are not native Perl scalars; they must be mapped to Perl’s internal representations correctly. This is especially important if you want to differentiate JSON booleans from strings or integers when parsing JSON or generating JSON output.
JSON Booleans in Perl
Perl itself doesn’t have a special boolean scalar type. Booleans are usually represented by undef, 0, or 1, but this can lead to confusion when handling JSON data. To handle JSON boolean values accurately, most Perl JSON modules provide a special boolean scalar type that behaves correctly in JSON contexts.
For example, the popular JSON and JSON::XS modules create and recognize special boolean values representing JSON’s true and false. These boolean values stringify as true or false in JSON output but behave as 1 or 0 in Perl boolean context.
Example Using JSON Module
Here’s a complete example that shows how to encode and decode JSON boolean values correctly using the JSON module (available in core Perl distributions since Perl 5.14+ or installable from CPAN):
use strict;
use warnings;
use JSON;
# Create a JSON object with boolean support enabled
my $json = JSON->new->allow_nonref;
# Original Perl data structure with JSON boolean values
my $data = {
active => JSON::true,
blocked => JSON::false,
count => 42,
};
# Encode Perl data with boolean scalars to JSON string
my $json_text = $json->encode($data);
print "Encoded JSON:\n$json_text\n";
# Decode JSON string back to Perl data
my $decoded = $json->decode($json_text);
# Check boolean values in Perl
print "Decoded boolean values:\n";
print "active: " . ($decoded->{active} ? "true\n" : "false\n");
print "blocked: " . ($decoded->{blocked} ? "true\n" : "false\n");
# Compare with standard Perl scalars
print "Comparison with ordinary Perl scalars:\n";
print "Is active identical to 1? " . ( ($decoded->{active} == 1) ? "yes\n" : "no\n" );
print "Is blocked identical to 0? " . ( ($decoded->{blocked} == 0) ? "yes\n" : "no\n" );
Explanation
JSON::trueandJSON::falseare special constants exported by theJSONmodule that represent JSON boolean values internally.- When encoding, these booleans are serialized as
trueorfalsein the JSON text (not as strings). - When decoding, the JSON booleans become these special scalar values that evaluate as 1 (true) or 0 (false) in Perl boolean context.
- You can safely test them using normal boolean expressions like
if ($decoded->{active}). - They differ from bare Perl scalars like integer 1 or 0 only in internal representation and stringification.
Common Pitfalls
- Using the plain Perl values
1or0in your data won’t serialize as JSON booleans but as numbers. - Using string values
"true"or"false"will serialize as JSON strings, not booleans. - Always use
JSON::trueandJSON::false(or equivalent fromJSON::XS) when constructing your Perl data structures for JSON output. - If you use another JSON module, check its documentation for the correct way to create boolean values.
Summary
Properly handling JSON boolean values in Perl involves using special boolean constants from your JSON encoder/decoder module. This ensures that true and false are encoded as JSON literals and decoded as proper boolean values in Perl. The JSON module makes this easy with JSON::true and JSON::false.
This approach maintains the semantic meaning of booleans, avoids confusion with strings or integers, and supports clean, correct JSON serialization and deserialization workflows in Perl.
Verified Code
Executed in a sandbox to capture real output. • v5.34.1 • 23ms
Encoded JSON:
{"count":42,"blocked":false,"active":true}
Decoded boolean values:
active: true
blocked: false
Comparison with ordinary Perl scalars:
Is active identical to 1? yes
Is blocked identical to 0? yes
(empty)