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.