2009-08-10 7 views

risposta

26

Yes. Da perldoc -f keys:

Le chiavi vengono restituite in un ordine apparentemente casuale. L'ordine casuale effettivo è soggetto a modifiche nelle versioni future di perl, ma è garantito lo stesso ordine di produzione della funzione values o each (poiché l'hash non è stato modificato). Poiché Perl 5.8.1 l'ordine è diverso anche tra diverse esecuzioni di Perl per ragioni di sicurezza (vedere "Algoritmic Complexity Attacks" in perldoc perlsec).

(sottolineatura mia)

+12

+1 Sarebbe bello se le persone cercassero almeno di leggere l'eccellente documentazione fornita con Perl. –

-2

Questa è un'aspettativa piuttosto rischiosa. Probabilmente lo sarà, ma perché preoccuparsi? Recupera le chiavi in ​​anticipo, salva il risultato, quindi esegui un'iterazione sul risultato salvato. Quindi, hai la garanzia di accedere alle chiavi nello stesso ordine. Lavorare ai margini di dettagli di implementazione non specificati è pericoloso.

MODIFICA: mancava la "garanzia" nel documento, ma continuo a pensare che sia pericoloso aspettarsi che questo non cambierà mai. Soprattutto quando ci sono modi più sani per raggiungere gli stessi fini.

+2

Perché le citazioni di paura intorno a "garanzia"?È (a) molto chiaramente dichiarato; (b) improbabile che cambi, perché è importante per 'keys' e' values' restituire nello stesso ordine, in modo che i due possano essere correlati per quando non è possibile usare 'each'. – derobert

0

Edit:

Anche se un hash normale ha un ordinamento coerente, nel caso di un tied hash l'ordine delle chiavi è non ben definito, in quanto è controllata dall'utente!


Anche se l'ordine tasto cancelletto non cambia, probabilmente dovrebbe riconsiderare il motivo per cui è necessario fare questo.

Forse è possibile elaborare l'hash in un passaggio anziché in due?

È necessario salvare le chiavi di hash in un array come pratica di programmazione difensiva, a meno che la dimensione dei dati sia sufficientemente ampia da duplicare il problema. Come bonus, puoi anche ordinare facilmente l'elenco e elaborare l'hash in un ordine ben definito. Per esempio,

my @keys = sort keys %myHash; 

Questo consente di evitare eventuali problemi con la modifica del hash, dal momento che l'ordine di matrice non cambierà mai a meno che non si desidera.

Se non lo fai, devi stare molto attento a non fare nulla che modifichi l'hash, altrimenti l'ordine degli elementi cambierà. Guarda nel modulo Readonly per assicurarti che questo hash non venga mai modificato.

+0

Non capisco - perché dovresti essere difensivo su una funzionalità testata, documentata e quindi garantita? Questo sembra sciocco come usare un editor di testo e chiamare File -> Safe due volte di fila nella speranza che se il primo fallisce in silenzio, il secondo avrà successo. – moritz

+2

@moritz: Il problema non è che Perl modifichi l'ordine delle chiavi (o meno), è che l'ordine può cambiare se l'hash è stato modificato. Questa risposta suggerisce una tattica difensiva di programmazione (array separato più Readonly) per il mantenimento futuro della base di codici dell'OP e non ha nulla a che vedere con gli interni di Perl. –

+3

A meno che non ci siano forti motivi di rendimento, cerco sempre di ordinare. È stato morso troppo spesso dal codice che prevede implicitamente un certo ordine e inizia a fallire misteriosamente quando modifiche apparentemente non correlate portano a un diverso ordine di chiavi. – ysth

Problemi correlati