Question

Je me débattais avec un Perl qui utilise des références de hachage.

Finalement, il s’est avéré que mon problème était la ligne:

$myhash{$key} |= {};

C’est-à-dire, "attribuez à $ myhash {$ key} une référence à un hachage vide, sauf s’il a déjà une valeur".

Le fait de déréférencer ceci et d’essayer de l’utiliser comme référence de hachage a toutefois entraîné des erreurs d’interpréteur lors de l’utilisation d’une chaîne comme référence de hachage.

Le changer pour:

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

... fait fonctionner les choses.

Je n'ai donc pas de problème . Mais je suis curieux de savoir ce qui se passait.

Quelqu'un peut-il expliquer?

Était-ce utile?

La solution

La raison pour laquelle vous voyez une erreur concernant l'utilisation d'une chaîne comme référence de hachage est parce que vous utilisez le mauvais opérateur. | = signifie "bitwise-or-assign." En d'autres termes,

  $foo |= $bar;

est identique à

  $foo = $foo | $bar

Ce qui se passe dans votre exemple, c'est que votre nouvelle référence de hachage anonyme est en train de devenir hiérarchisée, puis au niveau du bit-OR avec la valeur $ myhash {$ key} . Pour compliquer encore les choses, si $ myhash {$ key} n'est pas défini à ce moment-là, la valeur est la simple chaîne de caractères de la référence de hachage, qui ressemble à HASH (0x80fc284) . Ainsi, si vous effectuez une inspection superficielle de la structure, elle peut ressembler à une référence de hachage, mais ce n'est pas le cas. Voici quelques sorties utiles via Data :: Dumper :

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

Et voici ce que vous obtenez lorsque vous utilisez le bon opérateur:

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

Autres conseils

Perl a des opérateurs d’affectation abrégés. L'opérateur || = est souvent utilisé pour définir les valeurs par défaut des variables, car Perl permet aux opérateurs logiques de renvoyer la dernière valeur évaluée. Le problème est que vous avez utilisé | = qui est un bitwise ou à la place de || = qui est un logique ou.

À partir de Perl 5.10, il vaut mieux utiliser // = . // est l'opérateur défini -ou logique et n'échoue pas dans le coin où la valeur actuelle est définie mais fausse.

Je pense que votre problème était d'utiliser " | = " (au niveau du bit ou assignation) au lieu de " || = " (attribuer si faux).

Notez que votre nouveau code n'est pas exactement équivalent. La différence est que " $ myhash {$ key} || = {} " remplacera les valeurs existantes-mais-fausses par une référence de hachage, mais pas la nouvelle. En pratique, ce n'est probablement pas pertinent.

Essayez ceci:

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

Vous ne pouvez pas déclarer un élément de hachage dans une clause my , pour autant que je sache. Vous déclarez d'abord le hachage, puis ajoutez l'élément dans.

Modifier: je vois que vous avez retiré le mon . Pourquoi ne pas essayer || = au lieu de | = ? Le premier est idiomatique pour " paresseux " initialisation.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top