【问题标题】:creating hash from variables to be used in json encode/decode perl从要在 json 编码/解码 perl 中使用的变量创建哈希
【发布时间】:2012-01-05 04:45:09
【问题描述】:

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

【问题讨论】:

    标签: arrays json perl hash


    【解决方案1】:

    这一行

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

    【讨论】:

      【解决方案2】:

      问题在于 $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', ...},  
          ],
      }; 
      

      这也是一次声明整个数据结构的方式。

      【讨论】:

        猜你喜欢
        • 2015-08-25
        • 2015-03-26
        • 2013-12-20
        • 2016-07-25
        • 2011-04-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-14
        相关资源
        最近更新 更多