On Tue, Apr 24, 2012 at 08:45:32PM -0700, Father Chrysostomos via RT wrote:
> On Tue Apr 24 00:39:50 2012, nicholas wrote:
> > On Mon, Apr 23, 2012 at 03:13:39PM -0700, Father Chrysostomos via RT
> wrote:
> > > On Mon Apr 23 14:03:27 2012, nicholas wrote:
> > > > The intent of the changes appears to be to retain the 5.003 and
> > > > earlier
> > > > behaviour on what gets assigned for each construction, but change the
> > > > loop
> > > > behaviour to terminate on undefined rather than simply falsehood for
> > > > the
> > > > common simple cases:
> > > >
> > > > while (OP ...)
> > > >
> > > > and
> > > >
> > > > while ($var = OP ...)
> > >
> > > Except that while($var = each %h) implies defined(), but while(each %h)
> > > does not. So something got screwed up. :-)
> >
> > Yes. I *thought* that question was about while(each %h) [not] assigning to
> > $_, but I missed the [not] using defined.
> >
> > Pretty sure that the intent was that the intent at the time was to
> change it
> > to use defined. And I'd guess that it was missed because it's not the same
> > opcode structure.
Right. So history isn't quite what I thought it was.
while (<STDIN>)
while (<*>)
These both always implicitly assigned to $_, always implicitly added defined.
while ($_ = <STDIN>)
while ($a = <STDIN>)
while ($_ = <*>)
while ($a = <*>)
while ($_ = readdir D)
while ($a = readdir D)
while ($_ = each %h)
while ($a = each %h)
The implicit defined added was by commit 4b161ae29769b4a3,
//depot/maint-5.004/perl@949
BUT:
while (readdir D)
The implicit assignment to $_ and defined test were both added in *2009*
(by commit 114c60ecb1f7)
leaving:
while (each %h)
So it is the odd one out. And in 2009 we felt comfortable to add both the
implicit assignment and the defined test in blead for readdir, as a bug fix,
and have had no reports of it causing problems.
> > So that's a bug?
>
> That's what I was trying to ask. :-)
OK, after a quite a bit of deliberation and digging, I'm of the opinion that
1: yes, it's a bug
So, what on CPAN would be affected?
$ csearch 'while\s*\(\s*each'
/scratch/cpan/CSS-Inliner/t/ordering.t:while ( each %{$css} ) {$shuffle2++;}
This actually just seems to be counting the number of entries in the hash,
despite the comments:
#shuffle stored styles around
my $shuffle1 = 0;
foreach (keys %{$css}) { $shuffle1++;}
#shuffle stored styles around more
my $shuffle2 = 0;
while ( each %{$css} ) {$shuffle2++;}
/scratch/cpan/Games-Go-Player/lib/Games/Go/Player.pm: while (each %{$self->{$patternhash}}) {
(Inefficiently) counting the hash entries, in the debugging method tiestats():
while (each %{$self->{$patternhash}}) {
$count++;
}
/scratch/cpan/Geo-Ellipsoid/lib/Geo/Ellipsoid.pm: while( each %distance ) {}
# finish iterating to reset 'each' function call
while( each %distance ) {}
so, doesn't have any immediate side effects from also changing $_
(And could be more efficiently written)
/scratch/cpan/Math-NumSeq/lib/Math/NumSeq/JugglerSteps.pm: # while (each %cache) {
(Inefficiently) counting the hash entries, in debugging code:
# ### cache diagnostics ...
# my $count = 0;
# while (each %cache) {
# $count++;
# }
It's not really commented out code, as it's intended to be enabled by
using Devel::Comments - https://metacpan.org/module/Devel::Comments
/scratch/cpan/Noid/lib/Noid.pm:# $key = 0; while (each($noid, $key, $value)) { ... }
Typo in the documentation, should be eachnoid(...)
/scratch/cpan/Regexp-Fields/t/03-hash.t:while (each %{&}) { $count++ }
Quite intentionally testing the iterator:
"xyz" =~ /$rx/;
while (each %{&}) { $count++ }
is $count, 2, 'new match doesn\'t reset the iterator';
Documentation:
/scratch/cpan/SimpleCDB/SimpleCDB.pm:while (each %h) always shows as much data as you put in :-)
So, there's only one use of while(each %...) on CPAN outside of debugging or
test code, and that's only go the potential to break due to assignment now
happening to to $_. Compared with 29 matches for while\s*\(\s*readdir
of which 4 are .pm files. So
2: I think it's safe to fix it, just like readdir was fixed.
Nicholas Clark
Thread Previous
|
Thread Next