Login
RT #67760: RequireLexicalLoopIterators vs perl version
[gknop/Perl-Critic.git] / lib / Perl / Critic / Policy / Variables / RequireLexicalLoopIterators.pm
CommitLineData
6036a254 1##############################################################################
f7231315
JRT
2# $URL$
3# $Date$
4# $Author$
5# $Revision$
6036a254 6##############################################################################
f7231315
JRT
7
8package Perl::Critic::Policy::Variables::RequireLexicalLoopIterators;
9
df6dee2b 10use 5.006001;
f7231315
JRT
11use strict;
12use warnings;
c680a9c9 13use Readonly;
5920ee7c 14use version ();
c680a9c9 15
5920ee7c 16use Perl::Critic::Utils qw{ :booleans :severities };
f7231315
JRT
17use base 'Perl::Critic::Policy';
18
eed38807 19our $VERSION = '1.115';
f7231315 20
6036a254 21#-----------------------------------------------------------------------------
f7231315 22
c680a9c9
ES
23Readonly::Scalar my $DESC => q{Loop iterator is not lexical};
24Readonly::Scalar my $EXPL => [ 108 ];
f7231315 25
5920ee7c
TW
26Readonly::Scalar my $MINIMUM_PERL_VERSION => version->new( 5.004 );
27
6036a254 28#-----------------------------------------------------------------------------
f7231315 29
c680a9c9
ES
30sub supported_parameters { return () }
31sub default_severity { return $SEVERITY_HIGHEST }
32sub default_themes { return qw(core pbp bugs) }
33sub applies_to { return 'PPI::Statement::Compound' }
f7231315 34
6036a254 35#-----------------------------------------------------------------------------
f7231315 36
5920ee7c
TW
37sub prepare_to_scan_document {
38 my ( $self, $document ) = @_;
39 # perl5004delta says that is when lexical iterators were introduced,
40 # so ... (RT 67760)
41 my $version = $document->highest_explicit_perl_version();
42 return ! $version || $version >= $MINIMUM_PERL_VERSION;
43}
44
45#-----------------------------------------------------------------------------
46
f7231315
JRT
47sub violates {
48 my ( $self, $elem, undef ) = @_;
49
50 # First child will be 'for' or 'foreach' keyword
1631d324 51 return if $elem->type() ne 'foreach';
f7231315 52
ad277699
ES
53 my $first_child = $elem->schild(0);
54 return if not $first_child;
55 my $start = $first_child->isa('PPI::Token::Label') ? 1 : 0;
f7231315 56
ad277699
ES
57 my $potential_scope = $elem->schild($start + 1);
58 return if not $potential_scope;
59 return if $potential_scope->isa('PPI::Structure::List');
60
61 return if $potential_scope eq 'my';
45acb16b 62
c680a9c9 63 return $self->violation( $DESC, $EXPL, $elem );
f7231315
JRT
64}
65
6036a254 66#-----------------------------------------------------------------------------
f7231315
JRT
67
681;
69
70__END__
71
6036a254 72#-----------------------------------------------------------------------------
f7231315
JRT
73
74=pod
75
5920ee7c
TW
76=for stopwords foreach perlsyn
77
f7231315
JRT
78=head1 NAME
79
c5d07cb1 80Perl::Critic::Policy::Variables::RequireLexicalLoopIterators - Write C<for my $element (@list) {...}> instead of C<for $element (@list) {...}>.
f7231315 81
11f53956 82
af93c316
ES
83=head1 AFFILIATION
84
11f53956
ES
85This Policy is part of the core L<Perl::Critic|Perl::Critic>
86distribution.
af93c316
ES
87
88
f7231315
JRT
89=head1 DESCRIPTION
90
5920ee7c 91This policy asks you to use C<my>-style lexical loop iterator variables:
3d5e8c43 92
5920ee7c 93 foreach my $zed (...) {
11f53956
ES
94 ...
95 }
3d5e8c43 96
5920ee7c
TW
97Unless you use C<my>, C<for>/C<foreach> loops use a global variable with
98its value C<local> to the block. In other words,
3d5e8c43 99
5920ee7c 100 foreach $zed (...) {
11f53956
ES
101 ...
102 }
3d5e8c43 103
5920ee7c
TW
104is more-or-less equivalent to
105
106 {
107 local $zed
108 foreach $zed (...) {
109 ...
110 }
111 }
112
3d5e8c43
ES
113This may not seem like a big deal until you see code like
114
11f53956
ES
115 my $bicycle;
116 for $bicycle (@things_attached_to_the_bike_rack) {
117 if (
118 $bicycle->is_red()
119 and $bicycle->has_baseball_card_in_spokes()
120 and $bicycle->has_bent_kickstand()
121 ) {
122 $bicycle->remove_lock();
3d5e8c43 123
11f53956
ES
124 last;
125 }
126 }
3d5e8c43 127
11f53956
ES
128 if ( $bicycle and $bicycle->is_unlocked() ) {
129 ride_home($bicycle);
130 }
3d5e8c43 131
11f53956 132which is not going to allow you to arrive in time for dinner with your
5920ee7c
TW
133family because the C<$bicycle> outside the loop is not changed by the
134loop. You may have unlocked your bicycle, but you can't remember which
135one it was.
136
137Lexical loop variables were introduced in Perl 5.004. This policy does
138not report violations on code which explicitly specifies an earlier
b18262f2 139version of Perl (e.g. C<require 5.002;>).
3d5e8c43 140
0cb729f0
ES
141
142=head1 CONFIGURATION
143
49860482 144This Policy is not configurable except for the standard options.
0cb729f0
ES
145
146
5920ee7c
TW
147=head1 SEE ALSO
148
149L<"Foreach Loops" in perlsyn|perlsyn/Foreach Loops>
150
151L<"my() in Control Structures" in perl5004delta|perl5004delta/my() in control structures>
152
153
f7231315
JRT
154=head1 AUTHOR
155
03887e5e 156Jeffrey Ryan Thalhammer <jeff@imaginative-software.com>
f7231315 157
11f53956 158
f7231315
JRT
159=head1 COPYRIGHT
160
53b8903f 161Copyright (c) 2005-2011 Imaginative Software Systems. All rights reserved.
f7231315
JRT
162
163This program is free software; you can redistribute it and/or modify
164it under the same terms as Perl itself. The full text of this license
165can be found in the LICENSE file included with this module.
166
167=cut
737d3b65
CD
168
169# Local Variables:
170# mode: cperl
171# cperl-indent-level: 4
172# fill-column: 78
173# indent-tabs-mode: nil
174# c-indentation-style: bsd
175# End:
96fed375 176# ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :