File Coverage

blib/lib/Perl/Critic/Policy/Subroutines/ProhibitLvalueMethods.pm
Criterion Covered Total %
statement 25 26 96.1
branch 6 6 100.0
condition n/a
subroutine 9 10 90.0
pod 4 5 80.0
total 44 47 93.6


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::Subroutines::ProhibitLvalueMethods;
2 1     1   281864 use strict;
  1         3  
  1         32  
3 1     1   6 use warnings;
  1         2  
  1         57  
4              
5             our $VERSION = '0.001000';
6             $VERSION =~ tr/_//d;
7              
8 1     1   7 use parent qw(Perl::Critic::Policy);
  1         3  
  1         8  
9              
10 1         115 use Perl::Critic::Utils qw(
11             is_method_call
12             precedence_of
13 1     1   16555 );
  1         3  
14              
15       6 0   sub supported_parameters { }
16              
17 2     2 1 57 sub default_severity { return $Perl::Critic::Utils::SEVERITY_MEDIUM }
18 0     0 1 0 sub default_themes { return qw( ) }
19              
20 6     6 1 41972 sub applies_to { return 'PPI::Token::Word' }
21              
22             # match by precedence to catch other assignment ops, like ||=
23 1     1   7 use constant ASSIGNMENT_PRECEDENCE => precedence_of('=');
  1         4  
  1         7  
24              
25             my $DESC = 'Assignment to method "%s" used';
26             my $EXPL = <<'END_EXPL';
27             Use of methods as lvalues is uncommon and may indicate an accidental attempt
28             at assigning to a field or attribute, which is not commonly supported.
29             END_EXPL
30              
31             sub violates {
32 9     9 1 212 my ($self, $elem, undef) = @_;
33              
34 9 100       30 return if ! is_method_call($elem);
35              
36 6         346 my $sib = $elem;
37 6         22 while ($sib = $sib->snext_sibling) {
38 9 100       259 if ( $sib->isa( 'PPI::Token::Operator' ) ) {
39             return
40 3 100       9 if precedence_of( $sib->content ) != ASSIGNMENT_PRECEDENCE;
41 2         60 return $self->violation( sprintf($DESC, $elem->content), $EXPL, $sib );
42             }
43             }
44 3         78 return;
45             }
46              
47             1;
48             __END__
49              
50             =head1 NAME
51              
52             Perl::Critic::Policy::Subroutines::ProhibitLvalueMethods - Prohibit Methods
53             being used as lvalues
54              
55             =head1 SYNOPSIS
56              
57             In F<.perlcriticrc>:
58              
59             [Subroutines::ProhibitLvalueMethods]
60              
61             =head1 DESCRIPTION
62              
63             Use of methods as lvalues is uncommon. For less experienced Perl authors, or
64             author primarily experienced in other languages, lvalue methods can be
65             confusing or can get used accidentally.
66              
67             This policy blocks lvalue calls to methods. It does not block declaring a
68             method as lvalue.
69              
70             =head1 AUTHOR
71              
72             haarg - Graham Knop (cpan:HAARG) <haarg@haarg.org>
73              
74             =head1 CONTRIBUTORS
75              
76             None so far.
77              
78             =head1 COPYRIGHT
79              
80             Copyright (c) 2022 the Perl::Critic::Policy::Subroutines::ProhibitLvalueMethods
81             L</AUTHOR> and L</CONTRIBUTORS> as listed above.
82              
83             =head1 LICENSE
84              
85             This library is free software and may be distributed under the same terms
86             as perl itself. See L<https://dev.perl.org/licenses/>.
87              
88             =cut