Co `$ hash {$ key} | = {}` dělat v Perlu?

hlasů
3

Byl jsem zápasí s nějakým Perlu, který používá hash odkazy.

V závěru se ukázalo, že můj problém byl řádek:

$myhash{$key} |= {};

To znamená, že „přiřadit $ myhash {$ key} odkaz na lačný hash, pokud již má hodnotu“.

Dereferencing to a snaží se ji používat jako referenční hash se však mělo za následek chyby interpret o použití řetězce jako odkaz hash.

Změna na adresu:

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

... dělal věci fungují.

Takže já nemám problém . Ale jsem zvědavý, co se děje.

Může mi někdo vysvětlit?

Položena 30/09/2008 v 21:27
zdroj uživatelem
V jiných jazycích...                            


4 odpovědí

hlasů
2

Zkuste to:

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

Nemůžete deklarovat hashovací prvek v myklauzuli, pokud je mi známo. Deklarovat hash nejprve přidejte prvek.

Edit: Vidím, že jste vyjmuta my. Co takhle se snaží ||=místo |=? První z nich je osobitým pro „líné“ inicializace.

Odpovězeno 30/09/2008 v 21:30
zdroj uživatelem

hlasů
16

Perl má těsnopis operátory přiřazení. ||=Operátor je často používán k nastavení výchozí hodnoty pro proměnné kvůli funkce Perlu, že bude logické operátory vrátí poslední hodnotu hodnocen. Problém je v tom, že jste použili |=, což je bitový nebo místo ||=, které je logický nebo.

Jak Perl 5.10, že je lepší použít //=místo. //je logickým definované nebo provozovatel a neselže v rohovém případě, že je aktuální hodnota je definována, ale falešný.

Odpovězeno 30/09/2008 v 21:40
zdroj uživatelem

hlasů
4

Myslím, že váš problém byl s použitím „ |=“ (bitové-nebo postoupení) namísto „ ||=“ (přiřadit pokud false).

Všimněte si, že váš nový kód není přesně ekvivalentní. Rozdíl je v tom, že „ $myhash{$key} ||= {}“ nahradí stávající, ale nepravda hodnoty s odkazem hash, ale ten nový nebude. V praxi je to pravděpodobně není relevantní.

Odpovězeno 30/09/2008 v 21:41
zdroj uživatelem

hlasů
15

Důvodem, proč vidíte chybu o použití řetězec jako odkaz hash Je tomu tak proto, že používáte nesprávný operátor. |=znamená "bitové-or-Přiřadit." Jinými slovy,

  $foo |= $bar;

je stejné jako

  $foo = $foo | $bar

Co se děje ve vašem příkladu je, že vaše nová anonymní hash reference je stále stringified, pak bitové-ORed s hodnotou $myhash{$key}. To dále plete záležitosti, pokud $myhash{$key}je definována v té době, je hodnota jednoduchá stringification z Hash odkazu, který vypadá jako HASH(0x80fc284). Takže pokud si zběžnou prohlídku konstrukce, může to vypadat jako odkaz hash, ale to není. Zde je několik užitečných výstup přes Data::Dumper:

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

A tady je to, co dostanete, pokud použijete správnou operátora:

  perl -MData::Dumper -le '$hash{foo} ||= { }; print Dumper \%hash'
  $VAR1 = {
            'foo' => {}
          };
Odpovězeno 30/09/2008 v 21:47
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more