-1

モジュールを使用する Perl 結合ハッシュがあり、SDBM_File値を保存または取得するときに文字エンコーディング変換を行う必要があります。

のドキュメントperldbmfilterに従いましたが、一般的にはうまくいくようです:ハッシュから結果が期待どおりに適切にエンコードされ、エンコードのバイト値がファイルに保存され、16進エディターを使用してチェックされます。

keys機能していないのは、 、 またはeach、または のようなものを使用した、またはData::Dumper別のハッシュへの単純なコピー操作でさえ、ハッシュのすべての要素に対するあらゆる種類の反復です。

私がいつも得るのは無限再帰です。イテレータが最後に到達しないようeachです。反復された値を使用して出力すると、それらが繰り返されます。

の使用filter_fetch_keyとそこで行っている文字セット変換の問題を突き止めました。をコメント アウトするfilter_fetch_keyか、フィルター メソッドを変更して just を実行するとreturn shift、反復が再び機能します。これらのいずれかが私の問題を解決filter_fetch_keyしますが、適切にエンコードされた文字列を発信者に送信するために使用する必要があります。

$dbm->filter_fetch_key  (sub { $_ = $self->_normalizeCharset($_); });

sub _normalizeCharset
{
  my $self = shift || Carp::croak(...);

  #return shift;
  return ...::windows2utf(shift);
}

コメントを外すreturn shiftと、反復が機能します。しかし、上記のようにコメントしません。に何が起こるかは何かあると思いますが、指定されたデータをコピーして文字エンコーディングを行うだけ$_なので、わかりません。windows2utfこれは、キーと値を格納する場合や、値を取得する場合でも同じように機能します。キーのみが問題であり、特定のキーを直接要求する場合ではなく、反復を行う場合のみです。

私が間違っていることについてのヒントはありますか?

スレッドPerlmonksも付いています。

4

1 に答える 1

1

私は問題を発見しました: テスト中にfilter_fetch_key、キー値を指定して関数を 1 回呼び出し、関数undefがその場合の便宜のために空の文字列を返すことを認識しました。これが無限ループの原因のようです。何らかの理由でその空の文字列を新しいキーとしてハッシュに追加したい人がいると思いますが、無効になるイテレータなどで問題が発生します。それについての興味深い部分は、キーの変更は完全に問題ないということです。ドキュメントの例の1つがまさにそれについてであり、私のテストでは、undef好きなものを除いて各キーを置き換えることができるため、完全に新しいものを作成できます。たとえば、__を先頭に追加してキーを作成します。問題ありません、私が戻っundefてこない場合のみundef私は無限ループを取得します。次のメソッドの最初のバージョンは機能しますが、2 番目のバージョンは機能しません。

sub _normalizeCharset
{
  my $self  = shift || Carp::croak(...);
  my $value = shift;
  my $key = shift || 0;
return undef unless (defined($value));
#return '' unless (defined($value));

$value = "__$value" if ($key);

  return ...::windows2utf($value);
}


sub _normalizeCharset
{
  my $self  = shift || Carp::croak(...);
  my $value = shift;
  my $key = shift || 0;
#return undef unless (defined($value));
return '' unless (defined($value));

$value = "__$value" if ($key);

  return ...::windows2utf($value);
}

undef反復されたキーなどの終わりを示すフィルターの特別な信号である可能性があり、単に通常のハッシュキーを意味するものではないと思います。少なくとも私はどこにも入れません。

于 2014-09-09T09:35:54.570 に答える