serialization intermediate

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::true and JSON::false are special constants exported by the JSON module that represent JSON boolean values internally.
  • When encoding, these booleans are serialized as true or false in 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 1 or 0 in 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::true and JSON::false (or equivalent from JSON::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

Tip: edit code and use “Run (Browser)”. Server runs always execute the published, verified snippet.
STDOUT
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
STDERR
(empty)

Was this helpful?

Related Questions