develooper Front page | perl.perl5.porters | Postings from May 2012

Re: [perl #108286] Wishlist: Overridable keywords

Thread Previous | Thread Next
From:
Nicholas Clark
Date:
May 10, 2012 07:47
Subject:
Re: [perl #108286] Wishlist: Overridable keywords
Message ID:
20120510144712.GK2604@plum.flirble.org
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


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About