File Coverage

blib/lib/Perl/Critic/Policy/Variables/RequireLexicalLoopIterators.pm
Criterion Covered Total %
statement 37 37 100.0
branch 10 12 83.3
condition 2 3 66.6
subroutine 13 13 100.0
pod 5 6 83.3
total 67 71 94.3


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