14

私はPerlで小さな「DBQuery」関数を書きたいので、SQLステートメントを送信して返信するワンライナーと、ハッシュの配列、つまりレコードセットを作成できます。ただし、Perl 構文の問題 (およびおそらく奇妙なポインター/参照の問題) に遭遇しているため、データベースから取得しているハッシュから情報をパックすることができません。以下のサンプル コードは、この問題を示しています。

次の構文を使用して、配列内のハッシュからデータ "Jim" を取得できます。

print $records[$index]{'firstName'}

「ジム」を返します

しかし、最初に配列内のハッシュ レコードを独自のハッシュ変数にコピーすると、不思議なことにそのハッシュ内のデータにアクセスできなくなります。


    %row = $records[$index];
    $row{'firstName'};

"" (空白) を返します

問題を示す完全なサンプル コードを次に示します。どんな助けでも大歓迎です:


my @records = (
   {'id' => 1, 'firstName' => 'Jim'},
   {'id' => 2, 'firstName' => 'Joe'}
);
my @records2 = ();

$numberOfRecords = scalar(@records);
print "number of records: " . $numberOfRecords . "\n";
for(my $index=0; $index < $numberOfRecords; $index++) {

   #works
   print 'you can print the records like this: ' . $records[$index]{'firstName'} . "\n";

   #does NOT work
   %row = $records[$index];
   print 'but not like this: ' . $row{'firstName'} . "\n";

} 
4

6 に答える 6

23

ネストされたデータ構造には、ハッシュではなく、ハッシュ参照が含まれています。

# Will work (the -> dereferences the reference)
$row = $records[$index];
print "This will work: ", $row->{firstName}, "\n";

# This will also work, by promoting the hash reference into a hash
%row = %{ $records[$index] };
print "This will work: ", $row{firstName}, "\n";

深い Perl データ構造を提示されたことがあれば、Data::Dumperを使用してそれを人間が読める形式 (および Perl で解析可能な形式) に出力することで利益を得ることができます。

于 2008-09-09T04:03:09.247 に答える
5

ハッシュの配列には、実際にはハッシュが含まれていませんが、ハッシュへの参照が含まれています。この行:

%row = $records[$index];

%row に 1 つのエントリを割り当てます。キーはスカラーです:

   {'id' => 1, 'firstName' => 'Jim'},

これはハッシュへの参照ですが、値は空白です。

あなたが本当にやりたいことはこれです:

$row = $records[$index];
$row->{'firstName'};

またはそうでなければ:

$row = %{$records[$index];}
$row{'firstName'};
于 2008-09-09T04:08:39.093 に答える
4

他の人は、ハッシュとハッシュリファレンスについてコメントしています。言及する必要があると私が感じるもう 1 つのことは、DBQuery 関数です。DBI に既に組み込まれていることを実行しようとしているように見えますか? 私があなたの質問を正しく理解していれば、selectall_arrayrefのようなものを複製しようとしています:

このユーティリティ メソッドは、「準備」、「実行」、および「fetchall_arrayref」を 1 つの呼び出しに結合します。フェッチされたデータの各行の配列 (またはハッシュ、以下を参照) への参照を含む配列への参照を返します。

于 2008-09-09T06:48:39.740 に答える
3

上記の素敵な回答に追加するために、常に、常に、常に(はい、3つの「常に」)コードの上部で「警告を使用」を使用する必要があることを追加させてください。そのようにすると、「-e 行 1 で偶数サイズのリストが予期される場所に参照が見つかりました」という警告が表示されます。

于 2008-09-09T23:33:44.783 に答える
1

配列に実際にあるのは、ハッシュではなくハッシュリファレンスです。この概念を理解していない場合は、おそらくperlrefのドキュメントを読む価値があります。

必要なハッシュを取得するには

my %hash = %{@records[$index]};

例えば。

my @records = (
     {'id' => 1, 'firstName' => 'Jim'}, 
     {'id' => 2, 'firstName' => 'Joe'}
  );

  my %hash = %{$records[1]};

  print $hash{id}."\n";

それでも。学術目的でない限り、なぜこれをやりたいのかわかりません。それ以外の場合は、DBI モジュールで fetchall_hashref/fetchall_arrayref を使用するか、Class::DBI などを使用することをお勧めします。

于 2008-09-09T04:05:10.007 に答える
0

また、使用するのに適した perl イディオムは次のとおりです。

私の $rowHR ( @records ) {
   私の %row = %$rowHR;
   #それとも…
}

リストを反復処理します。

于 2008-09-16T09:22:17.283 に答える