A project I’ve been working on recently has meant me using both the JSON and JSON::Streaming::Reader Perl modules.
The JSON::Streaming::Reader is great for processing large files, and produces results that are compatible with the JSON module. Compatible… well almost. They both handle booleans in a slightly different way, and that caused me a few problems as I was mainly testing against the JSON module.
In JSON::Streaming::Reader boolean values become references to either 1 or 0.
The JSON module returns a JSON::Boolean (or if using XS – JSON::XS::Boolean) object that is either JSON::true, or JSON::False. These are overloaded to act as 1 or 0.
If you look at a Data::Dumper output, here are how they compare for a “true” value.
JSON::Streaming::Reader
$VAR1 = { 'OnSale' = 1 };
JSON
$VAR1 = { 'OnSale' => bless( do{(my $o = 1)}, 'JSON::XS::Boolean' ) };
For “false” the 1’s become 0’s.
When using the JSON module, because the JSON::Boolean object is overloaded, you can test for truthfullness by simply doing…
if ($decodedjson->{'OnSale'}) { ## This is true. }
However using JSON::Streaming::Reader this won’t work, as the reference will always evaluate to true. In this case the value must be dereferenced first before testing.
if (${$decodedjson->{'OnSale'}}) { ## This is true. }
The good news is that this same block of code will work when also using the JSON module, so in future, when testing decoded boolean values from JSON data, always dereference first!