我试图创建一个测试模块来测试json编码。我有问题创建将使用json编码/解码正确输出的变量。如果我只使用@cats数组中的$ cat_1,它将正常工作。然而,使用两者,它打印出" HASH(......"如下所示。
use strict;
use JSON;
use Data::Dump qw( dump );
my $cat_1 = {'name' => 'cat1', 'age' => '6', 'weight' => '10 kilos', 'type' => 'siamese'};
my $cat_2 = {'name' => 'cat2', 'age' => '10', 'weight' => '13 kilos', 'type' => 'siamese'};
my @cats;
push(@cats, $cat_1);
push(@cats, $cat_2);
my $dog_1 = {'name' => 'dog1', 'age' => '7', 'weight' => '20 kilos', 'type' => 'siamese'};
my $dog_2 = {'name' => 'dog2', 'age' => '5', 'weight' => '15 kilos', 'type' => 'siamese'};
my @dogs;
push(@dogs, $dog_1);
push(@dogs, $dog_2);
my $pets = {'cats' => @cats, 'dogs' => @dogs};
my $a = { 'id' => '123', 'name' => 'Joe Smith', 'city' => "Chicago", 'pets' => $pets };
my $json = JSON->new->allow_nonref;
my $encoded = $json->encode($a);
my $decoded = $json->decode( $encoded );
print "\ndump cat_1\n";
dump $cat_1;
print "\ndump cats\n";
dump @cats;
print "\n\nOriginal\n";
dump $a;
print "\n\n";
print "Encoded\n";
print $encoded;
print "\n\n";
print "Decoded\n";
dump $decoded;
print "\n\n";
输出
dump cat_1
{ age => 10, name => "cat1", type => "siamese", weight => "10 kilos" }
dump cats
(
{ age => 10, name => "cat1", type => "siamese", weight => "10 kilos" },
{ age => 10, name => "cat2", type => "siamese", weight => "3 kilos" },
)
Original
{
city => "Chicago",
id => 123,
name => "Joe Smith",
pets => {
"cats" => { age => 10, name => "cat1", type => "siamese", weight => "10 kilos" },
"HASH(0x176c3170)" => "dogs",
"HASH(0x1785f2d0)" => { age => 10, name => "dog2", type => "siamese", weight => "3 kilos" },
},
}
Encoded
{"city":"Chicago","pets":{"HASH(0x1785f2d0)":{"weight":"3 kilos","name":"dog2","type":"siamese","age":"10"},"cats":{"weight":"10 kilos","name":"cat1","type":"siamese","age":"10"},"HASH(0x176c3170)":"dogs"},"name":"Joe Smith","id":"123"}
Decoded
{
city => "Chicago",
id => 123,
name => "Joe Smith",
pets => {
"cats" => { age => 10, name => "cat1", type => "siamese", weight => "10 kilos" },
"HASH(0x176c3170)" => "dogs",
"HASH(0x1785f2d0)" => { age => 10, name => "dog2", type => "siamese", weight => "3 kilos" },
},
}
答案 0 :(得分:7)
这一行
my $pets = {'cats' => @cats, 'dogs' => @dogs};
是一面红旗。这是有效的Perl,但它并没有达到你所期望的效果。 Perl会在此构造中展平您的列表,因此如果@cats
包含($cat_1,$cat_2)
和@dogs
个符号($dog_1,$dog_2)
,则表达式将被解析为
my $pets = { 'cats', $cat_1, $cat_2, 'dogs', $dog_1, $dog_2 };
就像
my $pets = { 'cats' => $cat_1, $cat_2 => 'dogs', $dog_1 => $dog_2 }
使用哈希引用$cat_2
和$dog_1
在用作哈希键之前进行字符串化。
哈希值必须是标量值,而不是数组。但数组引用是可以的。尝试:
my $pets = {'cats' => \@cats, 'dogs' => \@dogs};
答案 1 :(得分:6)
问题在于创造$ pets:
my $pets = {'cats' => @cats, 'dogs' => @dogs};
大致相当于:
my $pets = {'cats', {name => 'cat1', ...}, {name => 'cat2', ...},
'dogs', {name => 'dog1', ...}, {name => 'dog2, ...} };
与以下内容相同:
my $pets = {
'cats' => {name => 'cat1', ...},
{name => 'cat2'}, => 'dogs',
{name => 'dog1', ...}, => {name => 'dog2}
};
您想使用ArrayRefs:
my $pets = {'cats' => \@cats, 'dogs' => \@dogs};
这是:
my $pets = {
'cats' => [
{name => 'cat1', ...},
{name => 'cat2', ...},
],
'dogs' => [
{name => 'dog1', ...},
{name => 'dog2', ...},
],
};
您也可以一次声明整个数据结构。