develooper Front page | perl.perl5.porters | Postings from May 2013

What does PERL_HASH_SEED do?

Thread Next
From:
Steve Hay
Date:
May 3, 2013 07:59
Subject:
What does PERL_HASH_SEED do?
Message ID:
67B2BB40A61BE846B65EF4793B863D6C98425C@ukmail02.planit.group
Reading perlrun, I thought that setting PERL_HASH_SEED to some integer
value would guarantee that the list returned by "keys %a" would be in
the same order for separate runs of a given build of perl, so that

perl -le "%a=(a=>1, b=>2, c=>3); print $a{$_} foreach (keys %a)"

would produce the same output every time (unless perl was compiled with
-DUSE_HASH_SEED_EXPLICIT, in which case the order would be the same
every time /unless/ PERL_HASH_SEED was set).

Have I misunderstood this? It doesn't work the way I've read it. I'm not
aware of having -DUSE_HASH_SEED_EXPLICIT set (I've just done a default
build on Windows), but regardless of whether PERL_HASH_SEED is set (to
0, or 1, or not set at all), the keys come out in a random order (not
that this data is at all pathological anyway). Setting
PERL_HASH_SEED_DEBUG=1 shows an effect on whether the HASH_SEED itself
is the same or different each time, but the output of the above is
different every time regardless:

D:\temp\blead>set PERL_HASH_SEED=

D:\temp\blead>perl -le "%a=(a=>1, b=>2, c=>3); print $a{$_} foreach
(keys %a)"
HASH_FUNCTION = ONE_AT_A_TIME_HARD HASH_SEED = 0x4bae3d3859341ed3
3
1
2

D:\temp\blead>perl -le "%a=(a=>1, b=>2, c=>3); print $a{$_} foreach
(keys %a)"
HASH_FUNCTION = ONE_AT_A_TIME_HARD HASH_SEED = 0xa75eeb6771a146d3
1
2
3

D:\temp\blead>set PERL_HASH_SEED=0

D:\temp\blead>perl -le "%a=(a=>1, b=>2, c=>3); print $a{$_} foreach
(keys %a)"
HASH_FUNCTION = ONE_AT_A_TIME_HARD HASH_SEED = 0x0000000000000000
2
3
1

D:\temp\blead>perl -le "%a=(a=>1, b=>2, c=>3); print $a{$_} foreach
(keys %a)"
HASH_FUNCTION = ONE_AT_A_TIME_HARD HASH_SEED = 0x0000000000000000
1
3
2

D:\temp\blead>set PERL_HASH_SEED=1

D:\temp\blead>perl -le "%a=(a=>1, b=>2, c=>3); print $a{$_} foreach
(keys %a)"
HASH_FUNCTION = ONE_AT_A_TIME_HARD HASH_SEED = 0x1000000000000000
3
2
1

D:\temp\blead>perl -le "%a=(a=>1, b=>2, c=>3); print $a{$_} foreach
(keys %a)"
HASH_FUNCTION = ONE_AT_A_TIME_HARD HASH_SEED = 0x1000000000000000
3
1
2

Is it really just the HASH_SEED which PERL_HASH_SEED controls the
randomization or otherwise of? If so then I find the documentation in
perlrun very misleading. Not only does it speak of hash keys having the
same ordering with PERL_HASH_SEED set to an integer (which it further
says is the default behaviour anyway until pathological data is detected
during a hash key insertion), but it also speaks of being able to mimic
Perl 5.8.0 behaviour. That /does/ produce the keys in the same order
every time:

D:\temp\blead>D:\temp\perl580\bin\perl -le "%a=(a=>1, b=>2, c=>3); print
$a{$_} foreach (keys %a)"
3
1
2

D:\temp\blead>D:\temp\perl580\bin\perl -le "%a=(a=>1, b=>2, c=>3); print
$a{$_} foreach (keys %a)"
3
1
2

D:\temp\blead>D:\temp\perl580\bin\perl -le "%a=(a=>1, b=>2, c=>3); print
$a{$_} foreach (keys %a)"
3
1
2

Is there some way to get the keys out in the same order on every run of
a given build of perl (other than the obvious answer of explicitly
sorting them yourself)?

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About