3

Perl での逆参照について何か助けが得られるかどうか疑問に思っています。

DB にクエリを実行し、返されたものを反復処理する while ループがあります。次に、必要なデータをハッシュに書き込み、そのハッシュを配列にプッシュします。これはすべて、JSON 文字列の一部を構成しています。

ただし、ハッシュ自体ではなく、ハッシュへの参照のみをプッシュできます(あらゆる種類のことを試しました)。つまり、ループが(たとえば)3回行われると、JSON Iに同じものが3回表示されますPUTしようとしています。

コードは次のとおりです。

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;

助けてくれてありがとう!

4

2 に答える 2

6

while配列にプッシュしているハッシュ参照は、外側のレベル (ループの外側) でスコープされます。これは、参照されるハッシュが 1 つだけであることを意味します。同じハッシュへの参照を配列に複数回プッシュしています。ループの反復ごとに新しいハッシュが必要だと思います。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);
于 2012-04-11T14:42:22.180 に答える
1

FMcwhileが説明しているように、ループ内で自動化された匿名ハッシュを使用することをお勧めします。コードはそのように単純になり、

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;
于 2012-04-11T15:03:34.317 に答える