File Coverage

blib/lib/Perl/Critic/Policy/BuiltinFunctions/ProhibitLvalueSubstr.pm
Criterion Covered Total %
statement 37 37 100.0
branch 9 10 90.0
condition 2 3 66.6
subroutine 13 13 100.0
pod 5 6 83.3
total 66 69 95.6


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::BuiltinFunctions::ProhibitLvalueSubstr;
2              
3 40     40   27752 use 5.010001;
  40         198  
4 40     40   257 use strict;
  40         152  
  40         873  
5 40     40   231 use warnings;
  40         150  
  40         1092  
6 40     40   239 use Readonly;
  40         119  
  40         2419  
7 40     40   343 use version 0.77 ();
  40         836  
  40         1335  
8              
9 40     40   326 use Perl::Critic::Utils qw{ :severities :classification :language };
  40         163  
  40         2334  
10 40     40   15497 use parent 'Perl::Critic::Policy';
  40         151  
  40         257  
11              
12             our $VERSION = '1.146';
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 96     96 0 1620 sub supported_parameters { return () }
25 75     75 1 342 sub default_severity { return $SEVERITY_MEDIUM }
26 86     86 1 369 sub default_themes { return qw( core maintenance pbp ) }
27 36     36 1 123 sub applies_to { return 'PPI::Token::Word' }
28              
29             #-----------------------------------------------------------------------------
30              
31             sub prepare_to_scan_document {
32 37     37 1 114 my ( $self, $document ) = @_;
33             # perl5005delta says that is when the fourth argument to substr()
34             # was introduced, so ... (RT #59112)
35 37         171 my $version = $document->highest_explicit_perl_version();
36 37   66     229 return ! $version || $version >= $MINIMUM_PERL_VERSION;
37             }
38              
39             #-----------------------------------------------------------------------------
40              
41             sub violates {
42 336     336 1 698 my ($self, $elem, undef) = @_;
43              
44 336 100       669 return if $elem->content() ne 'substr';
45 6 100       40 return if ! is_function_call($elem);
46              
47 5         12 my $sib = $elem;
48 5         13 while ($sib = $sib->snext_sibling()) {
49 9 100       246 if ( $sib->isa( 'PPI::Token::Operator' ) ) {
50 3         15 my $rslt = $ASSIGNMENT_PRECEDENCE <=> precedence_of(
51             $sib->content() );
52 3 100       38 return if $rslt < 0;
53 1 50       10 return $self->violation( $DESC, $EXPL, $sib ) if $rslt == 0;
54             }
55             }
56 2         66 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 :