Perl - 对JSON :: XS :: Boolean执行布尔运算

时间:2017-08-16 14:30:25

标签: perl

我目前正在使用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]'

奇怪的是,andor运营商似乎行为正常:

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]'

2 个答案:

答案 0 :(得分:3)

要执行您希望他们执行的操作,JSON::XS::trueJSON::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尝试不返回布尔值(如果不需要)。