我将Perl数据结构传递给encode_json
,并使用其返回的值作为输入发布到restful API。
示例:
$data = (input1 => true);
$json_data = encode_json($data);
print $json_data; // Prints: ["input1":"true"]
$url= http://api.example.com/resources/getDataAPI
$headers = {Accept => 'application/json', Authorization => 'Basic ' . encode_base64($username . ':' . $password)};
$client = REST::Client->new();
$client->POST($url,($json_data,$headers));
这一切都很好。
最近,另一位开发人员进行了很少的输入参数验证检查,REST严格接受布尔值,没有引号。
我现在需要将输入发送为
$data = '["inout1":true]'
$client = REST::Client->new();
$client->POST($url,($data,$headers));
我的所有脚本都失败了,因为输入数据使用encode_json
函数编码为JSON格式。
我可以手动形成JSON数据,但输入数据有时非常庞大。无法识别它们并随时修改。
有没有办法可以实现没有引号的传递布尔值?
答案 0 :(得分:13)
直接在Perl中使用true
和false
是use strict
下的语法错误,因为 barewords 是不允许的。
我猜您使用的是JSON或JSON::XS。那些使用标量引用来表示TRUE
和FALSE
。具体而言,\1
和\0
。
$data = ( input1 => \1 );
这是相关的doc from JSON::XS,它允许Types::Serializer::True和Types :: Serializer :: False:
来自Types :: Serialiser模块的这些特殊值分别变为JSON true和JSON false值。如果需要,您也可以直接使用
\1
和\0
。
the doc from JSON,也可以使用JSON::true
和JSON::false
:
这些特殊值分别变为JSON true和JSON false值。如果需要,您也可以直接使用
\1
和\0
。
如果您坚持在true
中使用不带引号的my $foo = true
,则可以生成返回\1
和\0
的子或常量(实际上是子)。< / p>
use constant false => \0;
sub true () { return \1 } # note the empty prototype
$data = ( input1 => true, input2 => false );
作为Sinan points out in his comment,使用常量会更快,除非你包含一个空原型(子定义中的()
),因为这样Perl可以内联调用。
但在我看来,这不仅仅是简单地使用参考文献。总是想想下一个处理这段代码的人。
答案 1 :(得分:1)
与 simbabque 的答案相反,我真的不认为将引用用作 \1
和 \0
来生成 true
和 {{1 }} 在 JSON 中。
JSON module 中的常量不仅仅是为了方便。
如果您使用这样的常量,您仍然可以在 Perl 中将它们计算为 false
或 true
值,而 false
和 \0
都计算为 {{1} } 在 Perl 中。
并且使用这些常量,除了在 Perl 中保留布尔值之外,还将在 JSON 中工作以生成正确的数据。
这是我所说的一个例子:
\1
该代码将输出如下内容:
true
如您所见,引用 use 5.010;
use strict;
use warnings;
use JSON qw(encode_json decode_json);
my $data = {
true_1 => JSON::true,
true_2 => \1,
false_1 => JSON::false,
false_2 => \0,
};
for my $key (sort keys %$data) {
say "$key value is $data->{$key} and is evaluated as true" if $data->{$key};
say "$key value is $data->{$key} and is evaluated as false" if not $data->{$key};
}
say encode_json $data;
(false_1 value is 0 and is evaluated as false
false_2 value is SCALAR(0x146f39b4c18) and is evaluated as true
true_1 value is 1 and is evaluated as true
true_2 value is SCALAR(0x146f3998918) and is evaluated as true
{"true_2":true,"false_1":false,"false_2":false,"true_1":true}
) 的值在 Perl 中被评估为 \0
,而设置的值因为 false_2
在 Perl 评估中仍然是 true
。
另外可以看到,在打印JSON::false
和false
的值时,它们会自动转换为JSON::true
和JSON::false
,而1
和 0
被打印为 \1
和 \0
。
最后,当转换为 SCALAR(0x146f3998918)
时,两者都可以正常工作。但是在 Perl 数据结构中设置应该为假的“真”值(SCALAR(0x146f39b4c18)
,空字符串或 JSON
),可能会导致代码的其他部分出现错误,您可能会在这些部分使用相同的结构和评估布尔字段来做某事。
此外,在开发级别,与将引用视为 0
和 {{1 }} 并且如果他/她不熟悉这种技巧,则无法理解引用的原因。
如果您真的想避免输入那些额外的 6 个字符,那么您可以在代码顶部执行此操作:
undef
然后您可以简单地将它们用作代码中的常量,如下所示:
JSON::true
虽然,也许常量名称应该全部大写(如 JSON::false
和 \1
),但这是一个不同的讨论主题。
因此,在使用 Perl 和 JSON 时,请始终使用 \0
和 use JSON qw(encode_json decode_json);
sub true () { JSON::true }
sub false () { JSON::false }
。它们将在 Perl 中得到很好的评估,它们在 JSON 中被转换为正确的数据类型,并且它们可以正确地打印到控制台和文件。 $data = {
is_member => true,
is_suspended => false,
}
也是如此。