Perl - De-Referencing Hash

时间:2012-04-11 14:24:55

标签: json perl

我只是想知道如果我能在Perl中解除引用的帮助吗?

我有一个while循环,我在查询数据库并迭代我得到的东西。然后我将我需要的数据写入哈希并将哈希值推送到数组中。这都是JSON字符串的一部分。

但是,我只能将引用推送到哈希而不是哈希本身(我已尝试过各种各样的事情),这意味着如果循环进行(例如)3次,我会得到同样的东西出现3次我想要的JSON。

以下是代码:

my $json = new JSON::XS;
my $json_text = JSON::XS->new->decode (shift->content);
my $sig_num = 0;
my %sig_hash;
<MySQL Stuff -removed for readability>

while($query_handle->fetch()) 
    {
    $sig_num++;
    $sig_hash{position} = 'below';
    $sig_hash{signature_text} = $sig;
    $sig_hash{signature_name} = 'Signature '.$sig_num;
    $sig_hash{signature_default} = JSON::XS::true;
    push (@{$json_text->{data}->{mail}->{signatures}}, \%sig_hash);
    }
return $json_text;

感谢您的帮助!

2 个答案:

答案 0 :(得分:6)

您正在推送到数组的散列引用的作用域位于外层(while循环之外)。这意味着只引用了一个哈希:您正在多次将对同一哈希的引用推送到该阵列。我假设你想要循环的每次迭代都有一个新的哈希值。如果是这样,请在循环内而不是外部声明my %sig_hash

您可以尝试使用此脚本来查看差异。先按原样运行;然后将my %h移到循环外部并再次运行。

my @data;

for (1..3){
    my %h;              # New hash for each iteration of the loop.
    $h{a} = 10 * $_;
    $h{b} = 20 * $_;
    push @data, \%h;
}

use Data::Dumper;
print Dumper(\@data);

答案 1 :(得分:1)

我建议您使用 autovivified 匿名哈希,正如FMc在while循环中所解释的那样。代码变得更简单,变成

my $json = new JSON::XS;
my $json_text = JSON::XS->new->decode(shift->content);
my $sig_num = 0;

while ($query_handle->fetch) {
  my $sig_hash;
  $sig_hash->{position} = 'below';
  $sig_hash->{signature_text} = $sig;
  $sig_hash->{signature_name} = "Signature ".++$sig_num;
  $sig_hash->{signature_default} = JSON::XS::true;
  push @{$json_text->{data}{mail}{signatures}}, $sig_hash;
}

return $json_text;

或者如果您愿意,可以将匿名哈希直接构建并推送到堆栈而不将其分配给变量

my $json = new JSON::XS;
my $json_text = JSON::XS->new->decode(shift->content);
my $sig_num = 0;

while ($query_handle->fetch) {
  push @{$json_text->{data}{mail}{signatures}}, {
    position => 'below',
    signature_text => $sig,
    signature_name => "Signature ".++$sig_num,
    signature_default => JSON::XS::true,
  };
}

return $json_text;