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

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

Thread Previous | Thread Next
Aristotle Pagaltzis
March 29, 2013 17:06
Re: Perlfunc for each(), keys(), values() has been changed
Message ID:
* demerphq <> [2013-03-29 12:40]:
> Each of the three functions entry in perlfunc now has the following
> paragraph:
> +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.
> I'll postpone fixing it for awhile to see if there are any further
> changes recommended by the list.

IMO this mentions too many specifics of the current implementation’s
behaviour – it would require revision the next time the hashing changes.

But the specific behaviour now is really quite irrelevant. (Even more so
is defending why it got to be that way; IMO that merits mention only as
gory details for the curious.) The point of interest to a programmer
consulting the docs is guidance on what to *do*: how to write correct
code; not background on what Perl does and why. IMO that is the emphasis
with which it should be written.

So how about this? Or something along these lines.

    Entries in a hash have a repeatable but arbitrary order. Therefore
    the order in which they are returned from C<keys>, C<values> and
    C<each> will match. Adding or deleting any keys changes this order
    arbitrarily and irreversibly, and you should expect the same set of
    keys in different hashes (or even in the same hash after adding and
    deleting keys) to yield a different order of entries. A special
    exception to this is made to allow you to safely delete keys from
    a hash while iterating over it: the entry most recently returned
    from C<each> or C<keys> can be deleted without changing the order of
    the other entries. Any and all other assumptions about hash ordering
    will make your code incorrect, even when it seems to work. (The
    exact likelihood of this depends on the implementation of hashes,
    which may differ between different versions of Perl. See also
    L<perlsec/"Algorithmic Complexity Attacks">.)

Aristotle Pagaltzis // <>

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About