File Coverage

blib/lib/Perl/Critic/Policy/Freenode/Each.pm
Criterion Covered Total %
statement 24 25 96.0
branch 2 2 100.0
condition 2 3 66.6
subroutine 10 11 90.9
pod 4 5 80.0
total 42 46 91.3


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::Freenode::Each;
2              
3 1     1   714 use strict;
  1         3  
  1         30  
4 1     1   5 use warnings;
  1         2  
  1         28  
5              
6 1     1   6 use Perl::Critic::Utils qw(:severities :classification :ppi);
  1         1  
  1         58  
7 1     1   378 use parent 'Perl::Critic::Policy';
  1         2  
  1         5  
8              
9             our $VERSION = '0.033';
10              
11 1     1   88 use constant DESC => 'each() called';
  1         3  
  1         72  
12 1     1   7 use constant EXPL => 'The each function may cause undefined behavior when operating on the hash while iterating. Use a foreach loop over the hash\'s keys or values instead.';
  1         1  
  1         194  
13              
14 2     2 0 7897 sub supported_parameters { () }
15 2     2 1 28 sub default_severity { $SEVERITY_LOW }
16 0     0 1 0 sub default_themes { 'freenode' }
17 2     2 1 27635 sub applies_to { 'PPI::Token::Word' }
18              
19             sub violates {
20 9     9 1 462 my ($self, $elem) = @_;
21 9 100 66     26 return () unless $elem eq 'each' and is_function_call $elem;
22 2         794 return $self->violation(DESC, EXPL, $elem);
23             }
24              
25             1;
26              
27             =head1 NAME
28              
29             Perl::Critic::Policy::Freenode::Each - Don't use each to iterate through a hash
30              
31             =head1 DESCRIPTION
32              
33             The C<each()> function relies on an iterator internal to a hash (or array),
34             which is the same iterator used by C<keys()> and C<values()>. So deleting or
35             adding hash elements during iteration, or just calling C<keys()> or C<values()>
36             on the hash, will cause undefined behavior and the code will likely break. This
37             could occur even by passing the hash to other functions which operate on the
38             hash. Instead, use a C<foreach> loop iterating through the keys or values of
39             the hash.
40              
41             while (my ($key, $value) = each %hash) { ... } # not ok
42             foreach my $key (keys %hash) { my $value = $hash{$key}; ... } # ok
43             foreach my $i (0..$#array) { my $elem = $array[$i]; ... } # ok
44              
45             =head1 AFFILIATION
46              
47             This policy is part of L<Perl::Critic::Freenode>.
48              
49             =head1 CONFIGURATION
50              
51             This policy is not configurable except for the standard options.
52              
53             =head1 AUTHOR
54              
55             Dan Book, C<dbook@cpan.org>
56              
57             =head1 COPYRIGHT AND LICENSE
58              
59             Copyright 2015, Dan Book.
60              
61             This library is free software; you may redistribute it and/or modify it under
62             the terms of the Artistic License version 2.0.
63              
64             =head1 SEE ALSO
65              
66             L<Perl::Critic>, L<http://blogs.perl.org/users/rurban/2014/04/do-not-use-each.html>