File Coverage

blib/lib/Perl/Critic/Policy/Variables/ProhibitAugmentedAssignmentInDeclaration.pm
Criterion Covered Total %
statement 33 33 100.0
branch 6 6 100.0
condition 3 3 100.0
subroutine 13 13 100.0
pod 4 5 80.0
total 59 60 98.3


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::Variables::ProhibitAugmentedAssignmentInDeclaration;
2              
3 40     40   27160 use 5.010001;
  40         186  
4 40     40   282 use strict;
  40         166  
  40         895  
5 40     40   248 use warnings;
  40         115  
  40         1344  
6 40     40   312 use List::SomeUtils qw( firstval );
  40         113  
  40         1978  
7 40     40   289 use Readonly;
  40         112  
  40         1959  
8              
9 40     40   331 use Perl::Critic::Utils qw{ :severities :data_conversion };
  40         122  
  40         1979  
10 40     40   6687 use parent 'Perl::Critic::Policy';
  40         154  
  40         241  
11              
12             our $VERSION = '1.146';
13              
14             #-----------------------------------------------------------------------------
15              
16             Readonly::Scalar my $DESC => q{Augmented assignment operator '%s' used in declaration};
17             Readonly::Scalar my $EXPL => q{Use simple assignment when initializing variables};
18              
19             #-----------------------------------------------------------------------------
20              
21             sub supported_parameters {
22             return (
23             {
24 96     96 0 2097 name => 'allow_our',
25             description =>
26             q<Allow augmented assignment for our variables.>,
27             default_string => '0',
28             behavior => 'boolean',
29             },
30             );
31             }
32 147     147 1 610 sub default_severity { return $SEVERITY_HIGH }
33 74     74 1 358 sub default_themes { return qw( core bugs ) }
34 38     38 1 132 sub applies_to { return 'PPI::Statement::Variable' }
35              
36             #-----------------------------------------------------------------------------
37              
38             my %augmented_assignments = hashify( qw( **= += -= .= *= /= %= x= &= |= ^= <<= >>= &&= ||= //= ) );
39              
40             sub violates {
41 177     177 1 445 my ( $self, $elem, undef ) = @_;
42              
43             # The assignment operator associated with a PPI::Statement::Variable
44             # element is assumed to be the first immediate child of that element.
45             # Other operators in the statement, e.g. the ',' in "my ( $a, $b ) = ();",
46             # as assumed to never be immediate children.
47             #
48             return
49 177 100 100     601 if $self->{_allow_our} and $elem->type eq 'our';
50              
51 175     874   1063 my $found = firstval { $_->isa('PPI::Token::Operator') } $elem->children();
  874         3437  
52 175 100       806 if ( $found ) {
53 174         493 my $op = $found->content();
54 174 100       1030 if ( exists $augmented_assignments{ $op } ) {
55 73         436 return $self->violation( sprintf( $DESC, $op ), $EXPL, $found );
56             }
57             }
58              
59 102         291 return;
60             }
61              
62              
63             1;
64              
65             __END__
66              
67             #-----------------------------------------------------------------------------
68              
69             =pod
70              
71             =for stopwords O'Regan
72              
73             =head1 NAME
74              
75             Perl::Critic::Policy::Variables::ProhibitAugmentedAssignmentInDeclaration - Do not write C< my $foo .= 'bar'; >.
76              
77              
78             =head1 AFFILIATION
79              
80             This Policy is part of the core L<Perl::Critic|Perl::Critic>
81             distribution.
82              
83              
84             =head1 DESCRIPTION
85              
86             Variable declarations that also do initialization with '=' are common.
87             Perl also allows you to use operators like '.=', '+=', etc., but it
88             it is more clear to not do so.
89              
90             my $foo .= 'bar'; # same as my $foo = 'bar';
91             our $foo *= 2; # same as our $foo = 0;
92             my ( $foo, $bar ) += ( 1, 2 ); # same as my ( $foo, $bar ) = ( undef, 2 );
93             local $Carp::CarpLevel += 1; # same as local $Carp::CarpLevel = 1;
94             state $foo += 2; # adds 2 every time it's encountered
95              
96             Such constructs are usually the result of botched cut-and-paste, and often are
97             bugs. Some produce warnings.
98              
99             =head1 CONFIGURATION
100              
101             There is an C<allow_our> boolean option for this Policy. If set, augmented
102             assignments are allowed when declaring C<our> variables. Since C<our>
103             variables are globally accessible, some modules will want to allow users to
104             initialize the variable prior to the module using the variable. Modules may
105             also wish to use the same our variable in different scopes without declaring
106             it at the outer scope.
107              
108             With this option set, the following are flagged as indicated:
109              
110             our $DEBUG //= 1; # ok
111              
112             This can be enabled in your F<.perlcriticrc>:
113              
114             [Perl::Critic::Policy::Variables::ProhibitAugmentedAssignmentInDeclaration]
115             allow_our = 1
116              
117             =head1 AUTHOR
118              
119             Mike O'Regan
120              
121              
122             =head1 COPYRIGHT
123              
124             Copyright (c) 2011-2021 Mike O'Regan. All rights reserved.
125              
126             This program is free software; you can redistribute it and/or modify
127             it under the same terms as Perl itself. The full text of this license
128             can be found in the LICENSE file included with this module.
129              
130             =cut
131              
132             # Local Variables:
133             # mode: cperl
134             # cperl-indent-level: 4
135             # fill-column: 78
136             # indent-tabs-mode: nil
137             # c-indentation-style: bsd
138             # End:
139             # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :