Hash key iteration order

  • Thread starter Krishna Chaitanya
  • Start date
K

Krishna Chaitanya

Hi, I was learning and reading about hash iterators. I am using Perl
5.8.8, and found that between 10 runs of Perl, the hash keys show up
in the same order.

======================

[kc@imits094 Perl]# for i in 1 2 3 4 5 6 7 8 9 10; do ./test.pl ; done
Keys of a are 6 3 7 9 2 8 1 4 10 5
Keys of a are 6 3 7 9 2 8 1 4 10 5
Keys of a are 6 3 7 9 2 8 1 4 10 5
Keys of a are 6 3 7 9 2 8 1 4 10 5
Keys of a are 6 3 7 9 2 8 1 4 10 5
Keys of a are 6 3 7 9 2 8 1 4 10 5
Keys of a are 6 3 7 9 2 8 1 4 10 5
Keys of a are 6 3 7 9 2 8 1 4 10 5
Keys of a are 6 3 7 9 2 8 1 4 10 5
Keys of a are 6 3 7 9 2 8 1 4 10 5
[kc@imits094 Perl]# cat test.pl
#!/usr/bin/perl

my %a;
@a{1..10} = ();

print "Keys of a are ", join(' ',keys %a), "\n";

==================

The description of "keys" function says: "Since Perl 5.8.1 the
ordering is different even between different runs of Perl for security
reasons (see Algorithmic Complexity Attacks in perlsec)."

And the perlsec page says: "In Perl 5.8.1 the random perturbation was
done by default, but as of 5.8.2 it is only used on individual hashes
if the internals detect the insertion of pathological data. If one
wants for some reason emulate the old behaviour (and expose oneself to
DoS attacks) one can set the environment variable PERL_HASH_SEED to
zero to disable the protection (or any other integer to force a known
perturbation, rather than random). One possible reason for wanting to
emulate the old behaviour is that in the new behaviour consecutive
runs of Perl will order hash keys differently, which may confuse some
applications (like Data::Dumper: the outputs of two different runs are
no longer identical)."

I'm confused...the ordering "is" different? or "may be" different
based on "insertion of pathological data"? But again, "the new
behaviour" above talks about different ordering of hash keys. In my
example, I don't think 1..10 is pathological data for keys...

Add to all this: "Also, the ordering of hash keys has always been, and
continues to be, affected by the insertion order."

I am totally out of my element here...can anyone shed some light on
this, please?

-KC
 
K

Krishna Chaitanya

If you can obey this maxim:

    Never rely on the order of hash keys.

Then you can ignore this question and move on to learning something
that you might be able to actually make use of.  :)

See also:

   http://www.perlmonks.org/?node_id=629429

Thanks a lot. That perlmonks link was curiously my very question, and
the answers there cleared some air. I actually do know the maxim which
you stated above and have followed it so far, but I got terminally
curious while reading up on functions like each and finding differing
tones regarding this matter in the documentation. I just wanted to
experiment with the iterator being common to each, keys, and values in
a single run, but was puzzled to see it behaving "predictably" across
runs too. That's what made me ask you folks here.

And yeah, I wouldn't consider this as useless information :) Who
knows, I could spot this problem in the code I inherited here at work,
or even help others who aren't aware of it. Have a nice day.
 
S

sln

Hi, I was learning and reading about hash iterators. I am using Perl
5.8.8, and found that between 10 runs of Perl, the hash keys show up
in the same order.

======================

[kc@imits094 Perl]# for i in 1 2 3 4 5 6 7 8 9 10; do ./test.pl ; done
Keys of a are 6 3 7 9 2 8 1 4 10 5
Keys of a are 6 3 7 9 2 8 1 4 10 5
Keys of a are 6 3 7 9 2 8 1 4 10 5
Keys of a are 6 3 7 9 2 8 1 4 10 5
Keys of a are 6 3 7 9 2 8 1 4 10 5
Keys of a are 6 3 7 9 2 8 1 4 10 5
Keys of a are 6 3 7 9 2 8 1 4 10 5
Keys of a are 6 3 7 9 2 8 1 4 10 5
Keys of a are 6 3 7 9 2 8 1 4 10 5
Keys of a are 6 3 7 9 2 8 1 4 10 5
[kc@imits094 Perl]# cat test.pl
#!/usr/bin/perl

my %a;
@a{1..10} = ();

print "Keys of a are ", join(' ',keys %a), "\n";

==================
[...]
I'm confused...the ordering "is" different? or "may be" different
based on "insertion of pathological data"? But again, "the new
behaviour" above talks about different ordering of hash keys. In my
example, I don't think 1..10 is pathological data for keys...

Add to all this: "Also, the ordering of hash keys has always been, and
continues to be, affected by the insertion order."

I am totally out of my element here...can anyone shed some light on
this, please?

I get different output within and between runs.
I added a funky add/delete key operation in the rand key
creation which throws off the order. Otherwise, even the
rand keys produce the same results as the slice
(the lines can be commented out for proof).
I would not have any ordering expectation for hash keys.

-sln

-------------------------
use strict;
use warnings;

for (1..5)
{
my (%a, @keys);
my $count = 1;
while ($count <= 10) {

$a{'938jun__+'} = ();
my $key = int( rand(11) );
if ($key > 0 && !exists( $a{$key} )) {
$a{$key} = ();
$count++;
push @keys, $key;
delete $a{'938jun__+'};
}
}
print "\nRand keys ... are @keys\n";
print "Keys of test1 are ", join(' ',keys %a), "\n";

%a = ();
@a{1..10} = ();

print "Keys of test2 are ", join(' ',keys %a), "\n";
}

__END__

Rand keys ... are 9 5 2 3 1 7 6 8 4 10
Keys of test1 are 6 3 7 9 2 8 4 1 10 5
Keys of test2 are 6 3 7 9 2 8 4 1 10 5

Rand keys ... are 6 3 9 2 4 5 10 8 1 7
Keys of test1 are 6 3 7 9 2 8 1 4 10 5
Keys of test2 are 6 3 7 9 2 8 4 1 10 5

Rand keys ... are 4 6 3 2 8 7 5 9 1 10
Keys of test1 are 6 3 7 9 2 8 1 4 10 5
Keys of test2 are 6 3 7 9 2 8 4 1 10 5

Rand keys ... are 4 3 5 7 9 10 8 2 6 1
Keys of test1 are 6 3 7 9 2 8 1 4 10 5
Keys of test2 are 6 3 7 9 2 8 4 1 10 5

Rand keys ... are 9 7 2 8 1 3 5 4 10 6
Keys of test1 are 6 3 7 9 2 8 4 1 10 5
Keys of test2 are 6 3 7 9 2 8 4 1 10 5
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top