Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the Perl-Critic CPAN distribution.

Report information
The Basics
Id: 67760
Status: resolved
Priority: 0/
Queue: Perl-Critic

People
Owner: Nobody in particular
Requestors: user42 [...] zip.com.au
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: (no value)
Fixed in: (no value)



Subject: RequireLexicalLoopIterators vs perl version [patch]
Date: Tue, 26 Apr 2011 09:38:42 +1000
To: bug-Perl-Critic [...] rt.cpan.org
From: Kevin Ryde <user42 [...] zip.com.au>
If I'm not mistaken the "for my $i" lexical loop vars of RequireLexicalLoopIterators are new in perl 5.004. It'd be good if that policy suppressed itself on code that's only "require 5.002", per the diff below. That'd be similar to what ProhibitThreeArgumentOpen, ProhibitTwoArgOpen and RequireUseWarnings do with respect to 5.6. Also, in the docs is an unadorned loop var "local" rather than lexical, strictly speaking. The distinction lexical vs local vs localized package var vs whatever is pretty subtle. It'd be good to make it clear, at least enough to explain the motivation for the policy ...
Index: RequireLexicalLoopIterators.pm =================================================================== --- RequireLexicalLoopIterators.pm (revision 4073) +++ RequireLexicalLoopIterators.pm (working copy) @@ -31,9 +31,17 @@ #----------------------------------------------------------------------------- +# foreach my $foo (...) is new in perl 5.004, +# per perl5004delta.pod "my() in Control Structures" +# +Readonly::Scalar my $MINIMUM_VERSION => version->new(5.004); + sub violates { - my ( $self, $elem, undef ) = @_; + my ( $self, $elem, $document ) = @_; + my $version = $document->highest_explicit_perl_version(); + return if $version && $version < $MINIMUM_VERSION; + # First child will be 'for' or 'foreach' keyword return if $elem->type() ne 'foreach'; @@ -73,17 +81,26 @@ =head1 DESCRIPTION -C<for>/C<foreach> loops I<always> create new lexical variables for -named iterators. In other words +This policy asks you to use C<my> style lexical loop iterator variables, - for $zed (...) { + for my $i (1 .. 10) { # good ... } +C<for>/C<foreach> loops localize the variable in a named iterator +(see L<perlsyn/"Foreach Loops">). In other words + + for $zed (...) { # bad + ... + } + is equivalent to - for my $zed (...) { + { + local $zed; + for $zed (...) { # $zed alias to each value ... + } } This may not seem like a big deal until you see code like @@ -106,16 +123,30 @@ } which is not going to allow you to arrive in time for dinner with your -family because the C<$bicycle> outside the loop is different from the -C<$bicycle> inside the loop. You may have freed your bicycle, but you +family because the C<$bicycle> outside the loop is not changed by the loop. +You may have unlocked your bicycle, but you can't remember which one it was. +=head2 Perl Version +Lexical loop variables are new in Perl 5.004 and higher. This policy doesn't +report violations if there's an explicit C<require 5.002> or similar +indicating the code is targeting an earlier Perl. + + =head1 CONFIGURATION This Policy is not configurable except for the standard options. +=head1 SEE ALSO + +L<Perl::Critic> + +L<perlsyn/"Foreach Loops">, +L<perl5004delta/"my() in Control Structures"> + + =head1 AUTHOR Jeffrey Ryan Thalhammer <jeff@imaginative-software.com>
-- The sigfile political applications of mathematics series: "The rate of increase of inflation is decreasing" -- Richard Nixon in 1972 applying a third derivative to his campaign for re-election.
On Mon Apr 25 19:39:23 2011, user42@zip.com.au wrote: Show quoted text
> If I'm not mistaken the "for my $i" lexical loop vars of > RequireLexicalLoopIterators are new in perl 5.004. It'd be good if that > policy suppressed itself on code that's only "require 5.002", per the > diff below. > > That'd be similar to what ProhibitThreeArgumentOpen, ProhibitTwoArgOpen > and RequireUseWarnings do with respect to 5.6. > > Also, in the docs is an unadorned loop var "local" rather than lexical, > strictly speaking. The distinction lexical vs local vs localized > package var vs whatever is pretty subtle. It'd be good to make it > clear, at least enough to explain the motivation for the policy ... > >
Thank you very much. I'm going to mark this wishlist, since it seems to me that anyone still running Perl 5.2 has chosen to undergo a certain amount of pain. On the other hand, patches are always appreciated, and give the maintainers an opportunity to cherry-pick. And yes, my understanding is that non-lexical loop variables are localized. Demonstrating that this is not _completely_ wrong, $ perl -le '$foo = 42; for $foo ( 1 .. 3 ) { print $foo } print $foo' prints 1 2 3 42 under both Perl 5.12.3 and Perl 5.6.2 (the oldest that compiles on my machine).
Changes committed as SVN revision 4074.
Subject: Re: [rt.cpan.org #67760] RequireLexicalLoopIterators vs perl version [patch]
Date: Thu, 28 Apr 2011 09:08:05 +1000
To: bug-Perl-Critic [...] rt.cpan.org
From: Kevin Ryde <user42 [...] zip.com.au>
"Tom Wyant via RT" <bug-Perl-Critic@rt.cpan.org> writes: Show quoted text
> > Changes committed as SVN revision 4074.
Beaut. But I wrote in the docs require 5.002 deliberately because use 5.002 is no good. "use 5.x" is new in 5.004. Earlier than that must be require. Per "use VERSION" in perl5004delta. I put a couple of lines in my Compatibility::PerlMinimumVersionAndWhy reporting on that, for actual code :-) It doesn't occur very often, but it's an easy mistake to make. Without picking on anyone for instance Devel::Symdump has "use 5.003", but running up 5.003 is syntax error at /usr/share/perl5/Devel/Symdump.pm line 3, near "use 5.003"
On Wed Apr 27 19:08:15 2011, user42@zip.com.au wrote: Show quoted text
> "Tom Wyant via RT" <bug-Perl-Critic@rt.cpan.org> writes:
> > > > Changes committed as SVN revision 4074.
> > Beaut. But I wrote in the docs > > require 5.002 > > deliberately because > > use 5.002 > > is no good. "use 5.x" is new in 5.004. Earlier than that must be > require. Per "use VERSION" in perl5004delta. > > > I put a couple of lines in my Compatibility::PerlMinimumVersionAndWhy > reporting on that, for actual code :-) It doesn't occur very often, but > it's an easy mistake to make. Without picking on anyone for instance > Devel::Symdump has "use 5.003", but running up 5.003 is > > syntax error at /usr/share/perl5/Devel/Symdump.pm line 3, near "use
5.003" This is actually an argument against trying to support really, really old Perls. Since the requisite infrastructure (specifically Perl::Critic::Document->highest_explicit_perl_version()) seems to support this, I will tweak the test and the docs. But if it had not, honestly, I would probably have retracted the update rather than fixing the infrastructure. After all, you are asking for support for a 15-year-old version of Perl -- there's only a limited extent to which that is even possible, and even when possible there is the question of whether it is a wise use of tuits. Committed as SVN revision 4076.
Subject: Re: [rt.cpan.org #67760] RequireLexicalLoopIterators vs perl version [patch]
Date: Thu, 28 Apr 2011 11:06:45 +1000
To: bug-Perl-Critic [...] rt.cpan.org
From: Kevin Ryde <user42 [...] zip.com.au>
"Tom Wyant via RT" <bug-Perl-Critic@rt.cpan.org> writes: Show quoted text
> > After all, you are asking for > support for a 15-year-old version of Perl
Well, not really, it's really for code which dates from then, or recently after, and has worked so well for so long that nobody has butchered about with it! Net::FTP for example perhaps ... There doesn't seem a great deal in the newer that's more than syntactic sugar etc ... except some of the enhanced regexp features which if you do need then are very helpful. :-)
On Wed Apr 27 21:06:55 2011, user42@zip.com.au wrote: Show quoted text
> "Tom Wyant via RT" <bug-Perl-Critic@rt.cpan.org> writes:
> > > > After all, you are asking for > > support for a 15-year-old version of Perl
> > Well, not really, it's really for code which dates from then, or > recently after, and has worked so well for so long that nobody has > butchered about with it! Net::FTP for example perhaps ... > > There doesn't seem a great deal in the newer that's more than syntactic > sugar etc ... except some of the enhanced regexp features which if you > do need then are very helpful. :-)
I'm trying to understand: if you don't intend to touch this code, why are you running Perl::Critic against it?