File Coverage

blib/lib/Perl/Critic/Policy/Variables/ProhibitAugmentedAssignmentInDeclaration.pm
Criterion Covered Total %
statement 33 34 97.0
branch 3 6 50.0
condition 1 3 33.3
subroutine 13 13 100.0
pod 4 5 80.0
total 54 61 88.5


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::Variables::ProhibitAugmentedAssignmentInDeclaration;
2              
3 40     40   26473 use 5.010001;
  40         175  
4 40     40   271 use strict;
  40         138  
  40         836  
5 40     40   231 use warnings;
  40         138  
  40         1143  
6 40     40   282 use List::SomeUtils qw( firstval );
  40         133  
  40         1861  
7 40     40   311 use Readonly;
  40         108  
  40         1985  
8              
9 40     40   297 use Perl::Critic::Utils qw{ :severities :data_conversion };
  40         149  
  40         2042  
10 40     40   6737 use parent 'Perl::Critic::Policy';
  40         137  
  40         288  
11              
12             our $VERSION = '1.150';
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 90     90 0 1993 name => 'allow_our',
25             description =>
26             q<Allow augmented assignment for our variables.>,
27             default_string => '0',
28             behavior => 'boolean',
29             },
30             );
31             }
32 74     74 1 347 sub default_severity { return $SEVERITY_HIGH }
33 74     74 1 339 sub default_themes { return qw( core bugs ) }
34 32     32 1 90 sub applies_to { return 'PPI::Statement::Variable' }
35              
36             #-----------------------------------------------------------------------------
37              
38             sub violates {
39 90     90 1 193 my ( $self, $elem, undef ) = @_;
40              
41 90         153 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 90 50 33     253 if $self->{_allow_our} and $elem->type eq 'our';
50              
51 90     450   419 my $found = firstval { $_->isa('PPI::Token::Operator') } $elem->children();
  450         1330  
52 90 50       328 if ( $found ) {
53 90         195 my $op = $found->content();
54 90 50       405 if ( exists $augmented_assignments->{ $op } ) {
55 0         0 return $self->violation( sprintf( $DESC, $op ), $EXPL, $found );
56             }
57             }
58              
59 90         213 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 :