我目前正在使用JSON::XS::Boolean
将布尔值正确编码为JSON
格式。有没有办法对这些对象执行布尔运算,同时保留它们正确编码的能力?
#!/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]'
奇怪的是,and
和or
运营商似乎行为正常:
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]'
答案 0 :(得分:3)
要执行您希望他们执行的操作,JSON::XS::true
和JSON::XS::false
返回的对象必须重载否定。他们没有。
你可以替换
!$p
与
$p ? JSON::XS::false : JSON::XS::true
或者您可以在事后对数据进行规范化。
AND和OR恰好起作用,因为它们总是返回其中一个输入。
Expression Returns when Returns when
$p is true $p is false
---------- ------------ ------------
$p || $q $p $q
$p && $q $q $p
类似的定义 - 返回输入的一个 - 不能存在于NOT中,因此它返回一个新值。
答案 1 :(得分:2)
好吧,首先,您的代码不会按照您的想法执行。我得到一个1和0的序列。
#!/usr/bin/env perl
use strict;
use warnings;
use JSON::XS::Boolean;
print(JSON::XS::true); # prints 'true'
print(!JSON::XS::false); # prints 1 instead of 'false'
print(JSON::XS::false and JSON::XS::false); # prints 'false'
print(JSON::XS::true && JSON::XS::true); # prints 'true'
print(JSON::XS::false and JSON::XS::true); # prints 'false'
print(JSON::XS::false || JSON::XS::false); # prints 'false'
print(JSON::XS::true or JSON::XS::true); # prints 'true'
print(JSON::XS::false || JSON::XS::true); # prints 'true'
输出:
11010011
但是,在尝试转换'boolean'类型时,您可能会遇到一些奇怪的行为,因为perl在您想的意义上没有布尔类型。它有“真实的东西”和“虚假的东西”。
“虚假的东西”是数字上为零的任何东西。 undef
。一个空字符串。
这就是事情 - 如果你做了'不真实'然后打印它,perl不知道它应该是哪些“错误的东西”。
所以,如果你这样做:
#!/usr/bin/env perl
use strict;
use warnings;
my $value = !1;
print "Value is: \'",$value,"\'\n";
Perl假设因为你在字符串上下文中使用它,所以你想要做字符串化的版本。
但那是因为$value
是一个dualvar
,其值0
和''
- 您可以在数字上添加它,这也会有效:
print "Value is: \'",$value+0,"\'\n";
注意 - 这不适用于'普通'空字符串 - 您将获得Argument "" isn't numeric in addition (+)
。
使用您编辑的代码 - 我可以非常肯定它是一样的。
#!/usr/bin/env perl
use strict;
use warnings;
use JSON::XS::Boolean;
use Scalar::Util qw ( isdual );
use Data::Dumper;
my $json = JSON::XS->new;
my $trueval = JSON::XS::true;
my $notfalse = !JSON::XS::false;
print Dumper $trueval;
print "\$trueval is a dualvar\n" if isdual($trueval);
print "Value = $trueval\n";
print Dumper $notfalse;
print "\$notfalse is a dualvar\n" if isdual($notfalse);
print "Value = $notfalse\n";
my $falseval = JSON::XS::false;
my $nottrue = !JSON::XS::true;
print Dumper $falseval;
print "\$falseval is a dualvar\n" if isdual($falseval);
print "Value = $falseval\n";
print Dumper $nottrue;
print "\$nottrue is a dualvar\n" if isdual($nottrue);
print "Value = $nottrue\n";
请注意$notfalse
如何不再是受祝福的JSON::PP::Boolean
?
输出:
$VAR1 = bless( do{\(my $o = 1)}, 'JSON::PP::Boolean' );
Value = 1
$VAR1 = 1;
$notfalse is a dualvar
Value = 1
$VAR1 = bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' );
Value = 0
$VAR1 = '';
$nottrue is a dualvar
Value =
!
将其转换为perl boolean的最接近的近似值。
然而||
不需要,因为perl会计算表达式并返回表达式的结果而不进行修改。
my $value = "some_text_here" || 0;
print $value;
and
/ or
正在“工作”,因为perl尝试不返回布尔值(如果不需要)。