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

Re: Perlfunc for each(), keys(), values() has been changed

Thread Previous | Thread Next
From:
demerphq
Date:
March 29, 2013 14:40
Subject:
Re: Perlfunc for each(), keys(), values() has been changed
Message ID:
CANgJU+VNTmfvd5Uqn8u9ZabJaze96f0_7pL=0uwxeRBO1jLF2Q@mail.gmail.com
On 29 March 2013 15:19, David Golden <xdg@xdg.me> wrote:
> On Fri, Mar 29, 2013 at 7:39 AM, demerphq <demerphq@gmail.com> wrote:
>> +Hash entries are returned in an apparently random order.  The actual random
>> +order is specific to a given hash; the exact same series of operations
>> +on two hashes may result in a different order for each hash. Any insertion
>> +into the hash may change the order, as will any deletion, with the exception
>> +that the most recent key returned by C<each> or C<keys> may be deleted
>> +without changing the order. So long as a given hash is unmodified you may
>> +rely on C<keys>, C<values> and C<each> to repeatedly return the same order
>> +as each other. See L<perlsec/"Algorithmic Complexity Attacks"> for
>> +details on why hash order is randomized. Aside from the guarantees
>> +provided here the exact details of Perl's hash algorithm and the hash
>> +traversal order are subject to change in any release of Perl
>
> Instead of "random" or "apparently random", how about "unpredictable"?

I was thinking "psudo-random". Im open to changing this, but this was
the original language and it seemed ok to keep it.

>  And possibly qualify it with something about within and across runs:
>
> "Hash entries are returned in an unpredictable order, both within a
> single program run and across multiple program runs."

I thought this was obvious from " The actual random
order is specific to a given hash; the exact same series of operations
on two hashes may result in a different order for each hash."

But id be happy to tweak it.

>
> Then, this amendment clarifies:
>
> "the exact same series of operations on two hashes *WITH IDENTICAL
> CONTENTS WILL LIKELY RESULT* in a different order for each hash".
>
> [Sure, a hash of 1 element will always have the same order, but the
> stronger statement sets better expectations]
>
> Then I think you should give an example:
>
>     %a = %b
>     say( join(" ", keys %a) eq join(" ", keys %b) ? "equal" :
> "unequal" ); # probably "unequal"

Ok.

> I don't understand what you mean by "most recent key returned by each
> or keys".  What is the most recent key returned by keys()?  Are you
> trying to say you can delete during each() without changing the order
> of subsequent keys/values returned by each()?

Well it means that

keys %hash; #reset each iterator
while (my $key= each %hash) {
  delete $hash{$key};
}

and

foreach my $key (keys %hash) {
  delete $hash{$key};
}

will never change the iteration order.

>
> And I would be specific about the guarantee.  Maybe:
>
> "Aside from the guarantee that the ordering of keys, value and each
> will be consistent for an unmodified hash, the implementation of
> Perl's hash algorithm and the resulting hash traversal order are
> subject to change without notice in any release of Perl."

Thats what the last sentence tries to say, but again, if you think
spelling it out in more detail is useful I have no objections.

Could I ask you to post what you think it should say as a full paragraph?

Yves

-- 
perl -Mre=debug -e "/just|another|perl|hacker/"

Thread Previous | 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