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