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 18:16
Re: Perlfunc for each(), keys(), values() has been changed
Message ID:
* Lukas Mai <> [2013-03-29 18:15]:
> This bit ("or C<keys>") makes no sense: 'keys' always returns
> a complete snapshot of the current keys. What does it mean for a key
> to be most recently returned from 'keys'?

The claim is from Yves’ text; I could not easily disprove it on the
older perls I have and did not compile blead to be sure. That is a very
minor point in the whole of my proposed text; it is a two-word deletion
that will not affect anything else.

* Brad Baxter <> [2013-03-29 18:20]:
> In the spirit of guidance on what to do, I think including the
> examples below to help understand "the entry most recently returned
> from C<each> or C<keys>" (particularly keys) would be helpful.

The `each` POD has such an example already. Do you feel that clarity
requires it to be repeated here?

* demerphq <> [2013-03-29 18:30]:
> On 29 March 2013 18:06, Aristotle Pagaltzis <> wrote:
> >* 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.
> Such as? (Honest question.)

I don’t know… but then that is the point. :-) Maybe there will be some
currently unfathomable reason to make sets of hashes sharing a seed or
something… doubtful of course, but I don’t think I will be able to come
up with an example until it happens, if it ever does. The thing is, it
*may* be read as promising something that p5p *may* want to change
later, and at the same time I do not see any counterbalancing value to
the programmer in explaining to them these specifics. It’s more useful
to both sides to emphasise Perl’s explicit promises and leave everything
else open.

> >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.
> I am inclined to say that should read:
> "and you should NOT expect the same set of keys in different hashes (or even
> in the same hash after adding or deleting keys) to yield the same
> order of entries."
> IOW, move the NOT from the end to the start....

Hmm. That does make it easier to read, however “you should not expect
them to be the same” is a weaker assertion than “you should expect them
to be different”. I am a little torn, but inclined to argue for sticking
with the proposal I made.

> > 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.
> I feel like we should make it really clear that this includes *any*
> version of perl, not just major versions.

Is that possible under perl’s binary compatibility promise? No argument
against any wording changes to that effect though.

> >See also
> >    L<perlsec/"Algorithmic Complexity Attacks">.)
> While I honestly don't think it really says anything different

It doesn’t, by design. But then neither did the original. :-)  The
difference is really only in emphasis, and clarity over the original.

> Also I was wondering if this paragraph shouldn't end up living in its
> own pod file somewhere, and be linked to instead of repeated in
> perlfunc.... Especially if we add more text to it like examples or
> whatever.

No opinion on that… I think this is a question for build system people
to consider.

Aristotle Pagaltzis // <>

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