4

ハッシュ参照を使用する Perl と格闘していました。

結局、私の問題は次の行であることが判明しました。

$myhash{$key} |= {};

つまり、「値がすでに存在しない限り、空のハッシュへの参照を $myhash{$key} に割り当てます」。

ただし、これを逆参照してハッシュ参照として使用しようとすると、文字列をハッシュ参照として使用することに関するインタープリター エラーが発生しました。

次のように変更します。

if( ! exists $myhash{$key}) {
  $myhash{$key} = {};
}

...物事を機能させました。

だから私は問題ありません。しかし、何が起こっていたのか興味があります。

誰でも説明できますか?

4

4 に答える 4

16

Perlには簡略代入演算子があります。||=論理演算子が最後に評価された値を返すようにするPerlの機能により、演算子は変数のデフォルト値を設定するためによく使用されます。問題は|=ビット単位または論理和の代わりに||=論理を使用したことです。

Perl 5.10以降では、//=代わりに使用することをお勧めします。//は論理的に定義された演算子であり、現在の値が定義されているがfalseであるコーナーケースでは失敗しません。

于 2008-09-30T20:40:13.443 に答える
16

文字列をハッシュ参照として使用することについてエラーが表示される理由は、間違った演算子を使用しているためです。|=「ビット単位または割り当て」を意味します。言い換えると、

  $foo |= $bar;

と同じです

  $foo = $foo | $bar

あなたの例で起こっていることは、あなたの新しい匿名ハッシュ参照が文字列化され、次に値とビットごとにORされているということです$myhash{$key}。さらに混乱させるため$myhash{$key}に、その時点でが未定義の場合、値はハッシュ参照の単純な文字列化であり、のようになりHASH(0x80fc284)ます。したがって、構造をざっと調べてみると、ハッシュ参照のように見えるかもしれませんが、そうではありません。以下を介していくつかの有用な出力がありますData::Dumper

   perl -MData::Dumper -le '$hash{foo} |= { }; print Dumper \%hash'
   $VAR1 = {
             'foo' => 'HASH(0x80fc284)'
           };

そして、正しい演算子を使用すると、次のようになります。

  perl -MData::Dumper -le '$hash{foo} ||= { }; print Dumper \%hash'
  $VAR1 = {
            'foo' => {}
          };
于 2008-09-30T20:47:12.740 に答える
4

あなたの問題は、 " "(falseの場合 |=は割り当て)の代わりに ""(ビット単位または割り当て)を使用していたと思います。||=

新しいコードは完全に同等ではないことに注意してください。違いは、 " $myhash{$key} ||= {}"は既存の偽の値をハッシュ参照に置き換えますが、新しい値は置き換えないことです。実際には、これはおそらく関係ありません。

于 2008-09-30T20:41:23.287 に答える
2

これを試して:

my %myhash;
$myhash{$key} ||= {};

私の知る限り、句でハッシュ要素を宣言することはできません。my最初にハッシュを宣言してから、要素を追加します。

編集: を取り出したようmyです。||=代わりに試してみては|=どうですか?前者は「怠惰な」初期化の慣用句です。

于 2008-09-30T20:30:03.187 に答える