File Coverage

blib/lib/Perl/Critic/Policy/BuiltinFunctions/ProhibitLvalueSubstr.pm
Criterion Covered Total %
statement 29 37 78.3
branch 1 10 10.0
condition 1 3 33.3
subroutine 13 13 100.0
pod 5 6 83.3
total 49 69 71.0


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::BuiltinFunctions::ProhibitLvalueSubstr;
2              
3 40     40   26054 use 5.010001;
  40         225  
4 40     40   324 use strict;
  40         150  
  40         836  
5 40     40   224 use warnings;
  40         143  
  40         1015  
6 40     40   255 use Readonly;
  40         129  
  40         2078  
7 40     40   312 use version 0.77 ();
  40         791  
  40         1245  
8              
9 40     40   313 use Perl::Critic::Utils qw{ :severities :classification :language };
  40         172  
  40         2347  
10 40     40   15484 use parent 'Perl::Critic::Policy';
  40         134  
  40         300  
11              
12             our $VERSION = '1.150';
13              
14             #-----------------------------------------------------------------------------
15              
16             Readonly::Scalar my $DESC => q{Lvalue form of "substr" used};
17             Readonly::Scalar my $EXPL => [ 165 ];
18              
19             Readonly::Scalar my $ASSIGNMENT_PRECEDENCE => precedence_of( q{=} );
20             Readonly::Scalar my $MINIMUM_PERL_VERSION => version->new( 5.005 );
21              
22             #-----------------------------------------------------------------------------
23              
24 89     89 0 1650 sub supported_parameters { return () }
25 74     74 1 290 sub default_severity { return $SEVERITY_MEDIUM }
26 86     86 1 351 sub default_themes { return qw( core maintenance pbp ) }
27 30     30 1 112 sub applies_to { return 'PPI::Token::Word' }
28              
29             #-----------------------------------------------------------------------------
30              
31             sub prepare_to_scan_document {
32 30     30 1 78 my ( $self, $document ) = @_;
33             # perl5005delta says that is when the fourth argument to substr()
34             # was introduced, so ... (RT #59112)
35 30         106 my $version = $document->highest_explicit_perl_version();
36 30   33     152 return ! $version || $version >= $MINIMUM_PERL_VERSION;
37             }
38              
39             #-----------------------------------------------------------------------------
40              
41             sub violates {
42 329     329 1 635 my ($self, $elem, undef) = @_;
43              
44 329 50       548 return if $elem->content() ne 'substr';
45 0 0         return if ! is_function_call($elem);
46              
47 0           my $sib = $elem;
48 0           while ($sib = $sib->snext_sibling()) {
49 0 0         if ( $sib->isa( 'PPI::Token::Operator' ) ) {
50 0           my $rslt = $ASSIGNMENT_PRECEDENCE <=> precedence_of(
51             $sib->content() );
52 0 0         return if $rslt < 0;
53 0 0         return $self->violation( $DESC, $EXPL, $sib ) if $rslt == 0;
54             }
55             }
56 0           return; #ok!
57             }
58              
59             1;
60              
61             #-----------------------------------------------------------------------------
62              
63             __END__
64              
65             =pod
66              
67             =for stopwords perlfunc substr 4th
68              
69             =head1 NAME
70              
71             Perl::Critic::Policy::BuiltinFunctions::ProhibitLvalueSubstr - Use 4-argument C<substr> instead of writing C<substr($foo, 2, 6) = $bar>.
72              
73              
74             =head1 AFFILIATION
75              
76             This Policy is part of the core L<Perl::Critic|Perl::Critic>
77             distribution.
78              
79              
80             =head1 DESCRIPTION
81              
82             Conway discourages the use of C<substr()> as an lvalue, instead
83             recommending that the 4-argument version of C<substr()> be used
84             instead.
85              
86             substr($something, 1, 2) = $newvalue; # not ok
87             substr($something, 1, 2, $newvalue); # ok
88              
89             The four-argument form of C<substr()> was introduced in Perl 5.005.
90             This policy does not report violations on code which explicitly
91             specifies an earlier version of Perl (e.g. C<use 5.004;>).
92              
93             =head1 CONFIGURATION
94              
95             This Policy is not configurable except for the standard options.
96              
97              
98             =head1 SEE ALSO
99              
100             L<"substr" in perlfunc|perlfunc/substr> (or C<perldoc -f substr>).
101              
102             L<"4th argument to substr" in perl5005delta|perl5005delta/4th argument to substr>
103              
104              
105             =head1 AUTHOR
106              
107             Graham TerMarsch <graham@howlingfrog.com>
108              
109              
110             =head1 COPYRIGHT
111              
112             Copyright (c) 2005-2011 Graham TerMarsch. All rights reserved.
113              
114             This program is free software; you can redistribute it and/or modify
115             it under the same terms as Perl itself.
116              
117             =cut
118              
119             # Local Variables:
120             # mode: cperl
121             # cperl-indent-level: 4
122             # fill-column: 78
123             # indent-tabs-mode: nil
124             # c-indentation-style: bsd
125             # End:
126             # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :