0

検索して検索しましたが、機能することがわかったコードを取得できません。これが古いことを繰り返している場合は申し訳ありませんが、私はこれらの10行を機能させるために、2日間を費やしました。私は、髪の毛が残っていない状態で終わりを迎えています:-(

私はPerl5.8.8を実行しています。

更新している単一のハッシュ変数の複数のコピーが含まれるように、Perlでハッシュの配列を設定したいと思います。私のコードはここにあります:

use strict;
use warnings;

my @array;

my %tempHash = (state => "apple", symbol => "54", memberId => "12345");
push(@array, \%tempHash);

%tempHash = (state => "tiger", symbol => "22", memberId => "12345");
push(@array, \%tempHash);

%tempHash = (state => "table", symbol => "37", memberId => "12345");
push(@array, \%tempHash);

printf("%p %p %p\n", $array[0], $array[1], $array[2]);

foreach my $entry (@array){
    printf("state: %s\n", $entry->{state});
    printf("memberId: %s\n", $entry->{memberId});
    printf("symbol: %s\n\n", $entry->{symbol});
}

これにより、次の出力が生成されます。

1868954 18688d0 18688c4
state: table
memberId: 12345
symbol: 37

state: table
memberId: 12345
symbol: 37

state: table
memberId: 12345
symbol: 37

したがって、配列内のスカラー値が異なるように見えます。ただし、これらのスカラーが指すハッシュの値はすべて同じです。

よろしくお願いします。

4

4 に答える 4

6

1)投稿したコードはで機能しませんuse strict;。%tempHashと%hashが実際に同じ変数であることを意味しますか?

2)%pの代わりに%sを使用すると、3つの同一のHASH(0x1234abcd)文字列が取得されます。これは、配列の内容が実際に同じハッシュへの参照であることを意味します。

3)毎回新しい匿名ハッシュを作成することをお勧めします:

#!/usr/bin/perl -w
use strict;
use Data::Dumper;

my @array;
my %tempHash = (state => "apple", symbol => "54",memberId => "12345");
push(@array, { %tempHash });

%tempHash = (state => "tiger", symbol => "22", memberId => "12345");
push(@array, { %tempHash });

%tempHash = (state => "table", symbol => "37", memberId => "12345");
push(@array, { %tempHash });

print Dumper( \@array );
于 2012-08-02T11:38:01.977 に答える
2

を使用してCSVファイルから一度に1行ずつデータをフェッチしているようですText::CSV

コードが次のようになっているとします

my %tempHash;
my @array;

while (my $line = $csv->getline($fh)) {
  # Add values to %tempHash;
  push @array, \%tempHash;
}

次に、ループ%tempHashのinsodeを宣言するだけで、問題を非常に簡単に解決できます。while

my @array;

while (my $line = $csv->getline($fh)) {
  my %tempHash;
  # Add values to %tempHash;
  push @array, \%tempHash;
}

Perlは、ブロックが入力されるたびに新しい字句ハッシュを作成するためです


アップデート

各入力レコードの後に​​データが必ずしも完全であるとは限らない場合は、次のように記述します。

my @array;
my $data = {};

while ( my $line = $csv->getline($fh) ) {
  # use information from $line to supplement $data
  if ($data is complete) {
    push @array, $data;
    $data = {};
  }
}
于 2012-08-02T12:29:39.020 に答える
1

もしあなたがtorスクリプトを追加use strictしたとuse warningsしたら、それは何が悪いのかを教えてくれたでしょう:

1つ目は、ハッシュを入力して、ハッシュtemphashへの参照を保存することです。次に、新しいhasを作成します。hash これを埋めますが、絶対に使用しないでください。temphash代わりに、 ...に新しい参照を追加します。

于 2012-08-02T11:32:55.490 に答える
0

私の賭けは、プッシュ機能は参照を気にしないということです。perldocを参照してください:

Perl 5.14以降、pushはスカラーEXPRを取得できます。これは、祝福されていない配列への参照を保持する必要があります。引数は自動的に逆参照されます。プッシュのこの側面は、非常に実験的であると考えられています。正確な動作は、Perlの将来のバージョンで変更される可能性があります。

編集

プッシュを使用しないようにすることができます:

my @array;
my %tempHash = (state => "apple", symbol => "54", memberId => "12345");
$#array=4;
$array[0]=\%tempHash;
$array[1]=\%tempHash;
$array[2]=\%tempHash;
printf("%p %p %p\n", $array[0], $array[1], $array[2]);
foreach my $entry (@array){
    printf("state: %s\n", $entry->{state});
    printf("memberId: %s\n", $entry->{memberId});
    printf("symbol: %s\n\n", $entry->{symbol});
}

私のperlインタプリタがちょうど私に言ったのと同じ結果で:-((perl 5.14.2)

于 2012-08-02T11:10:55.607 に答える