Q:

Perl - Performing boolean operations on JSON::XS::Boolean

I am currently using the JSON::XS::Boolean to properly encode booleans into JSON format.  Is there a way to perform boolean operations on these objects while preserving their ability to be encoded properly? 
#! /usr/bin/env perl
use strict;
use warnings;

use JSON::XS::Boolean;

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

print($json->encode([JSON::XS::true])); # prints '[true]'
print($json->encode([!JSON::XS::false])); # prints ["1"] instead of '[false]'

Curiously, the and and or operators seem to behave properly:
print($json->encode([JSON::XS::false and JSON::XS::false])); # prints '[false]'
print($json->encode([JSON::XS::true && JSON::XS::true])); # prints '[true]'
print($json->encode([JSON::XS::false and JSON::XS::true])); # prints '[false]'

print($json->encode([JSON::XS::false || JSON::XS::false])); # prints '[false]'
print($json->encode([JSON::XS::true or JSON::XS::true])); # prints '[true]'
print($json->encode([JSON::XS::false || JSON::XS::true])); # prints '[true]'

A:

To do what you want them to do, the objects returned by JSON::XS::true and JSON::XS::false would have to overload negation.  They don't. 
You could replace
! $p

with
$p ?  JSON::XS::false : JSON::XS::true

Or you could normalize your data after the fact. 

AND and OR happen to work because they always return one of their inputs. 
Expression  Returns when  Returns when
            $p is true    $p is false
----------  ------------  ------------
$p || $q    $p            $q
$p && $q    $q            $p

A similar definition —one that returns an input— can't exist for NOT, so it returns a fresh value.