We have encountered this problem as well.
The statement that returns the empty value is located in
JSON::Converter, line 206-207, in _valueToJson:
return $value # as is
if ($b_obj->FLAGS & B::SVf_IOK or $b_obj->FLAGS & B::SVf_NOK);
The problem seems to arise because Perl doesn't have a boolean data
type, so the value of !1 can be interpreted as both the number 0 or as
the empty string, as illustrated by Devel::Peek:
jfarrell@fnord:~$ perl -MDevel::Peek -e 'Dump(!1);'
SV = PVNV(0x607128) at 0x603b18
REFCNT = 2147483647
FLAGS = (PADBUSY,PADTMP,IOK,NOK,POK,READONLY,pIOK,pNOK,pPOK)
IV = 0
NV = 0
PV = 0x6070e0 ""\0
CUR = 0
LEN = 8
The purpose of lines 206-207 appears to be to determine if $value is a
number, in which case either one of the following two modifications
would likely solve the problem:
return $value + 0 # as is
if ($b_obj->FLAGS & B::SVf_IOK or $b_obj->FLAGS & B::SVf_NOK);
or
return $value # as is
if (($b_obj->FLAGS & B::SVf_IOK or $b_obj->FLAGS & B::SVf_NOK) and !(
$b_obj->FLAGS & B::SVf_POK ));
In the first case, {foo=>!1} would produce the JSON string '{"foo":0}'
In the second case, the JSON string would be '{"foo":""}'
Both of these seem acceptable. The optimal JSON version of {foo=>!1} is
probably '{"foo":false}', but given Perl's lack of a Boolean type, I'm
not sure how this could be produced, or whether it even should be.