从要在json编码/解码perl中使用的变量创建哈希

时间:2011-11-23 22:20:14

标签: arrays json perl hash

我试图创建一个测试模块来测试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" },
  },
}

2 个答案:

答案 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', ...},  
    ],
}; 

您也可以一次声明整个数据结构。