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

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

Thread Previous | Thread Next
From:
Paul Johnson
Date:
March 31, 2013 19:18
Subject:
Re: Perlfunc for each(), keys(), values() has been changed
Message ID:
20130331191806.GA4959@pjcj.net
On Sat, Mar 30, 2013 at 05:54:36PM +0100, demerphq wrote:

> Should it? We already say that if something inserts into the hash then
> the order changes, so if they simply delete the latest key, then the
> order shouldn't change at all. IOW, I believe the rules says that
> 
> my (%h,@k1,@k2);
> %h= ("A".."Z");
> delete $h{each %h};
> delete $h{each %h};
> while (my $k= each %h) { push @k1, $k }
> @k2= keys %h;
> is "@k1","@k2";
> 
> should pass.

First, thanks very much for all your work on this.

Which rules are you talking about here?  If you are meaning the prose
you wrote which started this thread, or Aristotle's amended text, then I
agree.  But if you are talking about the current documentation in 5.16.3
then I don't.

I did a little archaeology.  From the dawn of time (perl 1.0 patch 11)
the docs have said "You should not modify the array while iterating over
it."  Shortly thereafter, in perl 2.0 patch 1 that "should" became a
"must".

For 5.6.0 MJD gave us the current wording that "It is always safe to
delete the item most recently returned by each()" and in January 2012
Tom noted that this was "In the current implementation".

So based on the documentation of the last 25 years*, I don't think there
would be any expectation of that code passing.  Note that in this regard
the current text doesn't talk about the hash order, but rather about
safety and properly working code.  I think I prefer that approach.
Indeed, the implication is that the code above would probably fail since
the hash has been modified between the start of the iterations for
"each" and "keys", but this is not explicit.

In short, I have no objections to the above code passing but I don't
think the current (or past) documentation requires it, nor do I think
that we should be adding such requirements to the documentation.



* Perl 5 relaxed the constraints by saying "You should not add elements
to an array while you're iterating over it" and not mentioning deletion,
but deletion came back in 1997 with "If you add or delete elements of a
hash while you're iterating over it, you may get entries skipped or
duplicated, so don't."  I suspect this was just an oversight.

-- 
Paul Johnson - paul@pjcj.net
http://www.pjcj.net

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