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

bdi*_*zle 1 arrays perl hash json

我正在尝试创建一个测试模块来测试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";
Run Code Online (Sandbox Code Playgroud)

产量

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" },
  },
}
Run Code Online (Sandbox Code Playgroud)

mob*_*mob 7

这条线

my $pets = {'cats' => @cats, 'dogs' => @dogs};
Run Code Online (Sandbox Code Playgroud)

是一面红旗.这是有效的Perl,但它并没有达到你所期望的效果.Perl会汇整清单在这种结构中,因此,如果@cats包含($cat_1,$cat_2)@dogscontaints ($dog_1,$dog_2),你的表达被解析为

my $pets = { 'cats', $cat_1, $cat_2, 'dogs', $dog_1, $dog_2 };
Run Code Online (Sandbox Code Playgroud)

这就像

my $pets = { 'cats' => $cat_1, $cat_2 => 'dogs', $dog_1 => $dog_2 }
Run Code Online (Sandbox Code Playgroud)

使用哈希引用$cat_2$dog_1在用作哈希键之前进行字符串化.

散列值必须是标量值,而不是数组.但数组引用是可以的.尝试:

my $pets = {'cats' => \@cats, 'dogs' => \@dogs};
Run Code Online (Sandbox Code Playgroud)


Mar*_*mes 6

问题在于创建$ pets:

my $pets = {'cats' => @cats, 'dogs' => @dogs};
Run Code Online (Sandbox Code Playgroud)

大致相当于:

my $pets = {'cats', {name => 'cat1', ...}, {name => 'cat2', ...}, 
            'dogs', {name => 'dog1', ...}, {name => 'dog2, ...} };
Run Code Online (Sandbox Code Playgroud)

这与以下相同:

my $pets = {
            'cats'                 => {name => 'cat1', ...}, 
            {name => 'cat2'},      => 'dogs', 
            {name => 'dog1', ...}, => {name => 'dog2} 
           };
Run Code Online (Sandbox Code Playgroud)

您想使用ArrayRefs:

my $pets = {'cats' => \@cats, 'dogs' => \@dogs};
Run Code Online (Sandbox Code Playgroud)

这是:

my $pets = {
    'cats' => [
        {name => 'cat1', ...},
        {name => 'cat2', ...}, 
    ],      
    'dogs' => [ 
        {name => 'dog1', ...},
        {name => 'dog2', ...},  
    ],
}; 
Run Code Online (Sandbox Code Playgroud)

这也是您如何一次声明整个数据结构的方法.