2011-11-23 65 views
1

我試圖創建一個測試模塊來測試json編碼。我有問題創建變量,將正確輸出JSON編碼/解碼。如果我只使用@ cat數組中的$ cat_1,它將正常工作。然而,同時使用,它打印出 「HASH(...」 你可以看到下面。從json編碼/解碼中使用變量創建散列perl

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" }, 
    }, 
} 

回答

7

此行

my $pets = {'cats' => @cats, 'dogs' => @dogs}; 

是紅旗。這是有效的Perl,但它沒有達到你所期望的效果,Perl會將這個結構中的列表弄平,所以如果@cats包含($cat_1,$cat_2)@dogs containts ($dog_1,$dog_2),那麼你的e XPRESSION被解析爲

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}; 
+0

真棒。非常感謝。這工作。 – bdizzle

6

的問題是在創造$寵物:

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

這也是你如何能在一次聲明整個數據結構。

+0

非常感謝。這有助於解決問題。 – bdizzle