File Coverage

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


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::Variables::ProhibitAugmentedAssignmentInDeclaration;
2              
3 40     40   27052 use 5.010001;
  40         190  
4 40     40   273 use strict;
  40         121  
  40         951  
5 40     40   245 use warnings;
  40         107  
  40         1196  
6 40     40   276 use List::SomeUtils qw( firstval );
  40         133  
  40         2197  
7 40     40   296 use Readonly;
  40         108  
  40         2069  
8              
9 40     40   330 use Perl::Critic::Utils qw{ :severities :data_conversion };
  40         108  
  40         1958  
10 40     40   6748 use parent 'Perl::Critic::Policy';
  40         173  
  40         271  
11              
12             our $VERSION = '1.148';
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 2155 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 629 sub default_severity { return $SEVERITY_HIGH }
33 74     74 1 369 sub default_themes { return qw( core bugs ) }
34 38     38 1 131 sub applies_to { return 'PPI::Statement::Variable' }
35              
36             #-----------------------------------------------------------------------------
37              
38             sub violates {
39 177     177 1 422 my ( $self, $elem, undef ) = @_;
40              
41 177         344 state $augmented_assignments = { hashify( qw( **= += -= .= *= /= %= x= &= |= ^= <<= >>= &&= ||= //= ) ) };
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     617 if $self->{_allow_our} and $elem->type eq 'our';
50              
51 175     874   974 my $found = firstval { $_->isa('PPI::Token::Operator') } $elem->children();
  874         3374  
52 175 100       825 if ( $found ) {
53 174         503 my $op = $found->content();
54 174 100       994 if ( exists $augmented_assignments->{ $op } ) {
55 73         449 return $self->violation( sprintf( $DESC, $op ), $EXPL, $found );
56             }
57             }
58              
59 102         313 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-2023 Mike O'Regan
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 :