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   37002 use 5.010001;
  40         194  
4 40     40   320 use strict;
  40         143  
  40         931  
5 40     40   252 use warnings;
  40         115  
  40         1104  
6 40     40   265 use Readonly;
  40         163  
  40         2113  
7 40     40   344 use version ();
  40         144  
  40         1231  
8              
9 40     40   305 use Perl::Critic::Utils qw{ :booleans :severities };
  40         176  
  40         2283  
10 40     40   7079 use parent 'Perl::Critic::Policy';
  40         134  
  40         493  
11              
12             our $VERSION = '1.146';
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 1671 sub supported_parameters { return () }
24 78     78 1 438 sub default_severity { return $SEVERITY_HIGHEST }
25 92     92 1 416 sub default_themes { return qw(core pbp bugs certrec ) }
26 42     42 1 160 sub applies_to { return 'PPI::Statement::Compound' }
27              
28             #-----------------------------------------------------------------------------
29              
30             sub prepare_to_scan_document {
31 43     43 1 147 my ( $self, $document ) = @_;
32             # perl5004delta says that is when lexical iterators were introduced,
33             # so ... (RT 67760)
34 43         170 my $version = $document->highest_explicit_perl_version();
35 43   66     251 return ! $version || $version >= $MINIMUM_PERL_VERSION;
36             }
37              
38             #-----------------------------------------------------------------------------
39              
40             sub violates {
41 26     26 1 70 my ( $self, $elem, undef ) = @_;
42              
43             # First child will be 'for' or 'foreach' keyword
44 26 100       93 return if $elem->type() ne 'foreach';
45              
46 18         1244 my $first_child = $elem->schild(0);
47 18 50       237 return if not $first_child;
48 18 100       80 my $start = $first_child->isa('PPI::Token::Label') ? 1 : 0;
49              
50 18         64 my $potential_scope = $elem->schild($start + 1);
51 18 50       310 return if not $potential_scope;
52 18 100       74 return if $potential_scope->isa('PPI::Structure::List');
53              
54 14 100       46 return if $potential_scope eq 'my';
55              
56 4         75 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 :