line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
|
2
|
|
|
|
|
|
|
use strict; |
3
|
1
|
|
|
1
|
|
426
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
22
|
|
4
|
1
|
|
|
1
|
|
5
|
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
21
|
|
5
|
|
|
|
|
|
|
use List::Util 'any', 'none'; |
6
|
1
|
|
|
1
|
|
5
|
use Perl::Critic::Utils qw(:severities :classification :ppi); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
62
|
|
7
|
1
|
|
|
1
|
|
5
|
use parent 'Perl::Critic::Policy'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
50
|
|
8
|
1
|
|
|
1
|
|
314
|
|
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
6
|
|
9
|
|
|
|
|
|
|
our $VERSION = 'v1.0.3'; |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
|
12
|
4
|
|
|
4
|
0
|
31219
|
my %features = ( |
13
|
75
|
|
|
75
|
1
|
603
|
':=' => 'Use of := as an empty attribute list is deprecated in perl v5.12.0, use = alone.', |
14
|
0
|
|
|
0
|
1
|
0
|
'$[' => 'Use of $[ is deprecated in perl v5.12.0. See Array::Base and String::Base.', |
15
|
4
|
|
|
4
|
1
|
171828
|
'/\\C/' => 'Use of the \\C character class in regular expressions is deprecated in perl v5.20.0. To examine a string\'s UTF-8-encoded byte representation, encode it to UTF-8.', |
16
|
|
|
|
|
|
|
'?PATTERN?' => 'Use of ? as a match regex delimiter without an initial m is deprecated in perl v5.14.0. Use m?PATTERN? instead.', |
17
|
|
|
|
|
|
|
'autoderef' => 'Use of each/keys/pop/push/shift/splice/unshift/values on a reference is an experimental feature that is removed in perl v5.24.0. Dereference the array or hash to use these functions on it.', |
18
|
|
|
|
|
|
|
'Bare here-doc' => 'Use of bare << to create a here-doc with an empty string terminator is deprecated in perl 5. Use a quoted empty string like <<\'\'.', |
19
|
|
|
|
|
|
|
'chdir(\'\')' => 'Use of chdir(\'\') or chdir(undef) to chdir home is deprecated in perl v5.8.0. Use chdir() instead.', |
20
|
|
|
|
|
|
|
'defined on array/hash' => 'Use of defined() on an array or hash is deprecated in perl v5.6.2. The array or hash can be tested directly to check for non-emptiness: if (@foo) { ... }', |
21
|
|
|
|
|
|
|
'do SUBROUTINE(LIST)' => 'Use of do to call a subroutine is deprecated in perl 5.', |
22
|
|
|
|
|
|
|
'NBSP in \\N{...}' => 'Use of the "no-break space" character in character names is deprecated in perl v5.22.0.', |
23
|
|
|
|
|
|
|
'POSIX character function' => 'Several character matching functions in POSIX.pm are deprecated in perl v5.20.0: isalnum, isalpha, iscntrl, isdigit, isgraph, islower, isprint, ispunct, isspace, isupper, and isxdigit. Regular expressions are a more portable and correct way to test character strings.', |
24
|
|
|
|
|
|
|
'POSIX::tmpnam()' => 'The tmpnam() function from POSIX is deprecated in perl v5.22.0. Use File::Temp instead.', |
25
|
|
|
|
|
|
|
'qw(...) as parentheses' => 'Use of qw(...) as parentheses is deprecated in perl v5.14.0. Wrap the list in literal parentheses when required, such as in a foreach loop.', |
26
|
|
|
|
|
|
|
'require ::Foo::Bar' => 'Bareword require starting with a double colon is an error in perl v5.26.0.', |
27
|
|
|
|
|
|
|
'UNIVERSAL->import()' => 'The method UNIVERSAL->import() (or passing import arguments to "use UNIVERSAL") is deprecated in perl v5.12.0.', |
28
|
|
|
|
|
|
|
); |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
my %posix_deprecated = map { ($_ => 1, "POSIX::$_" => 1) } |
31
|
|
|
|
|
|
|
qw(isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit); |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
my %autoderef_functions = map { ($_ => 1) } |
34
|
|
|
|
|
|
|
qw(each keys pop push shift splice unshift values); |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
my ($self, $feature, $elem) = @_; |
37
|
|
|
|
|
|
|
my $desc = "$feature is deprecated"; |
38
|
|
|
|
|
|
|
my $expl = $features{$feature} // "$feature is deprecated or removed from recent versions of Perl."; |
39
|
|
|
|
|
|
|
return $self->violation($desc, $expl, $elem); |
40
|
|
|
|
|
|
|
} |
41
|
|
|
|
|
|
|
|
42
|
75
|
|
|
75
|
|
316
|
my ($self, $elem) = @_; |
43
|
75
|
|
|
|
|
184
|
my $next; |
44
|
75
|
|
33
|
|
|
177
|
my $prev; |
45
|
75
|
|
|
|
|
214
|
my $parent; |
46
|
|
|
|
|
|
|
my @args; |
47
|
|
|
|
|
|
|
my @violations; |
48
|
|
|
|
|
|
|
if ($elem->isa('PPI::Statement')) { |
49
|
1161
|
|
|
1161
|
1
|
5087
|
if ($elem->isa('PPI::Statement::Include')) { |
50
|
1161
|
|
|
|
|
3413
|
# use UNIVERSAL ...; |
51
|
|
|
|
|
|
|
if ($elem->type eq 'use' and defined $elem->module and $elem->module eq 'UNIVERSAL') { |
52
|
1161
|
|
|
|
|
0
|
my @args = $elem->arguments; |
53
|
1161
|
|
|
|
|
0
|
if (!@args or !$args[0]->isa('PPI::Structure::List') or $args[0]->schildren) { |
54
|
1161
|
|
|
|
|
0
|
push @violations, $self->_violation('UNIVERSAL->import()', $elem); |
55
|
1161
|
100
|
|
|
|
3472
|
} |
|
|
100
|
|
|
|
|
|
56
|
199
|
100
|
|
|
|
480
|
} |
57
|
|
|
|
|
|
|
# require ::Foo::Bar |
58
|
13
|
100
|
66
|
|
|
42
|
if (defined $elem->module and $elem->module =~ m/^::/) { |
|
|
|
100
|
|
|
|
|
59
|
3
|
|
|
|
|
181
|
push @violations, $self->_violation('require ::Foo::Bar', $elem); |
60
|
3
|
100
|
100
|
|
|
115
|
} |
|
|
|
66
|
|
|
|
|
61
|
2
|
|
|
|
|
6
|
} |
62
|
|
|
|
|
|
|
} elsif ($elem->isa('PPI::Token')) { |
63
|
|
|
|
|
|
|
if ($elem->isa('PPI::Token::Symbol')) { |
64
|
|
|
|
|
|
|
# $[ |
65
|
13
|
100
|
66
|
|
|
751
|
if ($elem eq '$[') { |
66
|
3
|
|
|
|
|
114
|
push @violations, $self->_violation('$[', $elem); |
67
|
|
|
|
|
|
|
} |
68
|
|
|
|
|
|
|
} elsif ($elem->isa('PPI::Token::Operator')) { |
69
|
|
|
|
|
|
|
# := |
70
|
903
|
100
|
|
|
|
5480
|
if ($elem eq ':' and $next = $elem->next_sibling and $next->isa('PPI::Token::Operator') and $next eq '=') { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
71
|
|
|
|
|
|
|
push @violations, $self->_violation(':=', $elem); |
72
|
92
|
100
|
|
|
|
228
|
# ?PATTERN? - PPI parses this as multiple ? operators |
73
|
1
|
|
|
|
|
115
|
} elsif ($elem eq '?' and $parent = $elem->parent and $parent->isa('PPI::Statement')) { |
74
|
|
|
|
|
|
|
$next = $elem->snext_sibling; |
75
|
|
|
|
|
|
|
until (!$next or ($next->isa('PPI::Token::Operator') and $next eq '?')) { |
76
|
|
|
|
|
|
|
$next = $next->snext_sibling; |
77
|
47
|
100
|
66
|
|
|
83
|
} |
|
|
100
|
100
|
|
|
|
|
|
|
100
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
78
|
1
|
|
|
|
|
50
|
# If the statement has a : operator, this is probably a ternary operator. |
79
|
|
|
|
|
|
|
# PPI also tends to detect the : as a loop label. |
80
|
|
|
|
|
|
|
if ($next and none { ($_->isa('PPI::Token::Operator') and $_ eq ':') or $_->isa('PPI::Token::Label') } $parent->schildren) { |
81
|
6
|
|
|
|
|
158
|
push @violations, $self->_violation('?PATTERN?', $elem); |
82
|
6
|
|
100
|
|
|
140
|
} |
|
|
|
100
|
|
|
|
|
83
|
14
|
|
|
|
|
242
|
# Bare here-doc - differentiate this from the legitimate << operator |
84
|
|
|
|
|
|
|
} elsif ($elem eq '<<' and (!($next = $elem->snext_sibling) |
85
|
|
|
|
|
|
|
or ($next->isa('PPI::Token::Operator') and $next ne '~' and $next ne '!' and $next ne '+' and $next ne '-') |
86
|
|
|
|
|
|
|
or ($next->isa('PPI::Token::Structure') and $next ne '(' and $next ne '{' and $next ne '['))) { |
87
|
6
|
100
|
100
|
17
|
|
201
|
push @violations, $self->_violation('Bare here-doc', $elem); |
|
17
|
100
|
100
|
|
|
189
|
|
88
|
1
|
|
|
|
|
3
|
} |
89
|
|
|
|
|
|
|
} elsif ($elem->isa('PPI::Token::Word')) { |
90
|
|
|
|
|
|
|
# UNIVERSAL->import() |
91
|
|
|
|
|
|
|
if ($elem eq 'UNIVERSAL' |
92
|
|
|
|
|
|
|
and $next = $elem->snext_sibling and $next->isa('PPI::Token::Operator') and $next eq '->' |
93
|
|
|
|
|
|
|
and $next = $next->snext_sibling and $next->isa('PPI::Token::Word') and $next eq 'import') { |
94
|
4
|
|
|
|
|
301
|
push @violations, $self->_violation('UNIVERSAL->import()', $next); |
95
|
|
|
|
|
|
|
# for $x qw(...) |
96
|
|
|
|
|
|
|
} elsif (($elem eq 'for' or $elem eq 'foreach') and !$elem->sprevious_sibling) { |
97
|
|
|
|
|
|
|
$next = $elem->snext_sibling; |
98
|
152
|
100
|
66
|
|
|
283
|
until (!$next or $next->isa('PPI::Structure::List') |
|
|
100
|
100
|
|
|
|
|
|
|
100
|
66
|
|
|
|
|
|
|
100
|
66
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
99
|
|
|
|
|
|
|
or $next->isa('PPI::Token::QuoteLike::Words')) { |
100
|
|
|
|
|
|
|
$next = $next->snext_sibling; |
101
|
1
|
|
|
|
|
83
|
} |
102
|
|
|
|
|
|
|
if ($next and $next->isa('PPI::Token::QuoteLike::Words')) { |
103
|
|
|
|
|
|
|
push @violations, $self->_violation('qw(...) as parentheses', $next); |
104
|
2
|
|
|
|
|
71
|
} |
105
|
2
|
|
66
|
|
|
71
|
# do SUBROUTINE(LIST) |
|
|
|
100
|
|
|
|
|
106
|
|
|
|
|
|
|
} elsif ($elem eq 'do' and $next = $elem->snext_sibling) { |
107
|
4
|
|
|
|
|
57
|
if ((($next->isa('PPI::Token::Word') and is_function_call $next) |
108
|
|
|
|
|
|
|
or ($next->isa('PPI::Token::Symbol') and ($next->raw_type eq '&' or $next->raw_type eq '$'))) |
109
|
2
|
100
|
66
|
|
|
61
|
and ($next = $next->snext_sibling and $next->isa('PPI::Structure::List'))) { |
110
|
1
|
|
|
|
|
4
|
push @violations, $self->_violation('do SUBROUTINE(LIST)', $elem); |
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
# avoid false positives for method calls |
113
|
|
|
|
|
|
|
} elsif (!($prev = $elem->sprevious_sibling) or !$prev->isa('PPI::Token::Operator') or $prev ne '->') { |
114
|
6
|
100
|
66
|
|
|
377
|
# POSIX character function or POSIX::tmpnam() |
|
|
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
115
|
|
|
|
|
|
|
if (exists $posix_deprecated{$elem} or $elem eq 'tmpnam' or $elem eq 'POSIX::tmpnam') { |
116
|
|
|
|
|
|
|
my $is_posix = $elem =~ m/^POSIX::/ ? 1 : 0; |
117
|
3
|
|
|
|
|
346
|
(my $function_name = $elem) =~ s/^POSIX:://; |
118
|
|
|
|
|
|
|
unless ($is_posix) { |
119
|
|
|
|
|
|
|
my $includes = $elem->document->find('PPI::Statement::Include') || []; |
120
|
|
|
|
|
|
|
foreach my $stmt (grep { ($_->module // '') eq 'POSIX' } @$includes) { |
121
|
|
|
|
|
|
|
my @args = $stmt->arguments; |
122
|
139
|
100
|
100
|
|
|
7886
|
$is_posix = 1 if !@args or any { $_ =~ m/\b\Q$function_name\E\b/ } @args; |
|
|
100
|
100
|
|
|
|
|
|
|
100
|
66
|
|
|
|
|
|
|
100
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
123
|
48
|
100
|
|
|
|
290
|
} |
124
|
48
|
|
|
|
|
245
|
} |
125
|
48
|
100
|
|
|
|
213
|
if ($is_posix) { |
126
|
36
|
|
50
|
|
|
91
|
push @violations, $self->_violation('POSIX::tmpnam()', $elem) if $function_name eq 'tmpnam'; |
127
|
36
|
|
50
|
|
|
175843
|
push @violations, $self->_violation('POSIX character function', $elem) if exists $posix_deprecated{$elem}; |
|
96
|
|
|
|
|
1282
|
|
128
|
36
|
|
|
|
|
879
|
} |
129
|
36
|
100
|
100
|
24
|
|
1107
|
# defined array/hash |
|
24
|
|
|
|
|
63
|
|
130
|
|
|
|
|
|
|
} elsif ($elem eq 'defined' and $next = $elem->snext_sibling) { |
131
|
|
|
|
|
|
|
$next = $next->schild(0) if $next->isa('PPI::Structure::List'); |
132
|
48
|
100
|
|
|
|
707
|
if ($next and $next->isa('PPI::Token::Symbol') |
133
|
36
|
100
|
|
|
|
92
|
and ($next->raw_type eq '@' or $next->raw_type eq '%') |
134
|
36
|
100
|
|
|
|
754
|
and $next->raw_type eq $next->symbol_type) { |
135
|
|
|
|
|
|
|
push @violations, $self->_violation('defined on array/hash', $elem); |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
# autoderef |
138
|
8
|
100
|
|
|
|
380
|
} elsif (exists $autoderef_functions{$elem} and $next = $elem->snext_sibling) { |
139
|
8
|
100
|
66
|
|
|
76
|
$next = $next->schild(0) if $next->isa('PPI::Structure::List'); |
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
140
|
|
|
|
|
|
|
$next = $next->schild(0) if $next and $next->isa('PPI::Statement::Expression'); |
141
|
|
|
|
|
|
|
if ($next and $next->isa('PPI::Token::Symbol') and $next->raw_type eq '$') { |
142
|
2
|
|
|
|
|
114
|
my $is_postderef; |
143
|
|
|
|
|
|
|
until (!$next or ($next->isa('PPI::Token::Structure') and $next eq ';') |
144
|
|
|
|
|
|
|
or ($next->isa('PPI::Token::Operator') and $next eq ',')) { |
145
|
|
|
|
|
|
|
$next = $next->snext_sibling; |
146
|
21
|
100
|
|
|
|
1091
|
if ($next and $next->isa('PPI::Token::Cast') and ($next eq '@*' or $next eq '%*')) { |
147
|
21
|
100
|
100
|
|
|
187
|
$is_postderef = 1; |
148
|
21
|
100
|
100
|
|
|
137
|
last; |
|
|
|
100
|
|
|
|
|
149
|
11
|
|
|
|
|
72
|
} |
150
|
11
|
|
66
|
|
|
76
|
} |
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
151
|
|
|
|
|
|
|
push @violations, $self->_violation('autoderef', $elem) unless $is_postderef; |
152
|
29
|
|
|
|
|
137
|
} |
153
|
29
|
50
|
100
|
|
|
645
|
} elsif ($elem eq 'chdir' and $next = $elem->snext_sibling) { |
|
|
|
66
|
|
|
|
|
|
|
|
100
|
|
|
|
|
154
|
3
|
|
|
|
|
55
|
$next = $next->schild(0) if $next->isa('PPI::Structure::List'); |
155
|
3
|
|
|
|
|
7
|
$next = $next->schild(0) if $next and $next->isa('PPI::Statement::Expression'); |
156
|
|
|
|
|
|
|
if ($next and (($next->isa('PPI::Token::Quote') and !length $next->string) |
157
|
|
|
|
|
|
|
or ($next->isa('PPI::Token::Word') and $next eq 'undef'))) { |
158
|
11
|
100
|
|
|
|
88
|
push @violations, $self->_violation('chdir(\'\')', $elem); |
159
|
|
|
|
|
|
|
} |
160
|
|
|
|
|
|
|
} |
161
|
7
|
100
|
|
|
|
420
|
} |
162
|
7
|
100
|
100
|
|
|
80
|
} elsif ($elem->isa('PPI::Token::Regexp')) { |
163
|
7
|
100
|
100
|
|
|
62
|
# ?PATTERN? |
|
|
|
100
|
|
|
|
|
164
|
|
|
|
|
|
|
if ($elem->isa('PPI::Token::Regexp::Match') and ($elem->get_delimiters)[0] eq '??' and $elem !~ m/^m/) { |
165
|
3
|
|
|
|
|
37
|
push @violations, $self->_violation('?PATTERN?', $elem); |
166
|
|
|
|
|
|
|
} |
167
|
|
|
|
|
|
|
if (!$elem->isa('PPI::Token::Regexp::Transliterate')) { |
168
|
|
|
|
|
|
|
push @violations, $self->_violates_interpolated($elem); |
169
|
|
|
|
|
|
|
} |
170
|
|
|
|
|
|
|
} elsif ($elem->isa('PPI::Token::HereDoc')) { |
171
|
8
|
50
|
100
|
|
|
37
|
# Bare here-doc |
|
|
|
66
|
|
|
|
|
172
|
0
|
|
|
|
|
0
|
if ($elem eq '<<') { |
173
|
|
|
|
|
|
|
push @violations, $self->_violation('Bare here-doc', $elem); |
174
|
8
|
50
|
|
|
|
140
|
} |
175
|
8
|
|
|
|
|
16
|
} elsif ($elem->isa('PPI::Token::QuoteLike')) { |
176
|
|
|
|
|
|
|
if ($elem->isa('PPI::Token::QuoteLike::Regexp') or $elem->isa('PPI::Token::QuoteLike::Backtick') or $elem->isa('PPI::Token::QuoteLike::Command')) { |
177
|
|
|
|
|
|
|
push @violations, $self->_violates_interpolated($elem); |
178
|
|
|
|
|
|
|
} |
179
|
3
|
50
|
|
|
|
7
|
} elsif ($elem->isa('PPI::Token::Quote')) { |
180
|
0
|
|
|
|
|
0
|
if ($elem->isa('PPI::Token::Quote::Double') or $elem->isa('PPI::Token::Quote::Interpolate')) { |
181
|
|
|
|
|
|
|
push @violations, $self->_violates_interpolated($elem); |
182
|
|
|
|
|
|
|
} |
183
|
12
|
100
|
100
|
|
|
84
|
} |
|
|
|
100
|
|
|
|
|
184
|
8
|
|
|
|
|
33
|
} |
185
|
|
|
|
|
|
|
return @violations; |
186
|
|
|
|
|
|
|
} |
187
|
14
|
100
|
100
|
|
|
73
|
|
188
|
5
|
|
|
|
|
15
|
my ($self, $elem) = @_; |
189
|
|
|
|
|
|
|
my @violations; |
190
|
|
|
|
|
|
|
# NBSP in \N{...} |
191
|
|
|
|
|
|
|
my $contents; |
192
|
1161
|
|
|
|
|
16649
|
if ($elem->isa('PPI::Token::Regexp') or $elem->isa('PPI::Token::QuoteLike::Regexp')) { |
193
|
|
|
|
|
|
|
$contents = $elem->get_match_string; |
194
|
|
|
|
|
|
|
# /\C/ |
195
|
|
|
|
|
|
|
push @violations, $self->_violation('/\\C/', $elem) if $contents =~ m/(?<!\\)\\C/; |
196
|
21
|
|
|
21
|
|
35
|
} elsif ($elem->isa('PPI::Token::Quote')) { |
197
|
21
|
|
|
|
|
33
|
$contents = $elem->string; |
198
|
|
|
|
|
|
|
} else { |
199
|
|
|
|
|
|
|
# Backticks and qx elements have no contents method |
200
|
21
|
100
|
100
|
|
|
90
|
$contents = $elem; |
|
|
100
|
|
|
|
|
|
201
|
12
|
|
|
|
|
38
|
} |
202
|
|
|
|
|
|
|
push @violations, $self->_violation('NBSP in \\N{...}', $elem) if $contents =~ m/\\N\{[^}]*\x{a0}[^}]*\}/; |
203
|
12
|
100
|
|
|
|
192
|
return @violations; |
204
|
|
|
|
|
|
|
} |
205
|
5
|
|
|
|
|
22
|
|
206
|
|
|
|
|
|
|
1; |
207
|
|
|
|
|
|
|
|
208
|
4
|
|
|
|
|
6
|
=head1 NAME |
209
|
|
|
|
|
|
|
|
210
|
21
|
100
|
|
|
|
394
|
Perl::Critic::Policy::Community::DeprecatedFeatures - Avoid features that have |
211
|
21
|
|
|
|
|
1017
|
been deprecated or removed from Perl |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
=head1 DESCRIPTION |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
While L<Perl::Critic::Policy::Community::StrictWarnings> will expose usage of |
216
|
|
|
|
|
|
|
deprecated or removed features when a modern perl is used, this policy will |
217
|
|
|
|
|
|
|
detect such features in use regardless of perl version, to assist in keeping |
218
|
|
|
|
|
|
|
your code modern and forward-compatible. |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
=head1 FEATURES |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
=head2 := |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
Because the whitespace between an attribute list and assignment operator is not |
225
|
|
|
|
|
|
|
significant, it was possible to specify assignment to a variable with an empty |
226
|
|
|
|
|
|
|
attribute list with a construction like C<my $foo := 'bar'>. This is deprecated |
227
|
|
|
|
|
|
|
in perl v5.12.0 to allow the possibility of a future C<:=> operator. Avoid the |
228
|
|
|
|
|
|
|
issue by either putting whitespace between the C<:> and C<=> characters or |
229
|
|
|
|
|
|
|
simply omitting the empty attribute list. |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
=head2 $[ |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
The magic L<perlvar/"$["> variable was used in very old perls to determine the |
234
|
|
|
|
|
|
|
index of the first element of arrays or the first character in substrings, and |
235
|
|
|
|
|
|
|
also allow modifying this value. It was discouraged from the start of Perl 5, |
236
|
|
|
|
|
|
|
its functionality changed in v5.10.0, deprecated in v5.12.0, re-implemented as |
237
|
|
|
|
|
|
|
L<arybase>.pm in v5.16.0, and it is essentially a synonym for C<0> under |
238
|
|
|
|
|
|
|
C<use v5.16> or C<no feature "array_base">. While it is probably a bad idea in |
239
|
|
|
|
|
|
|
general, the modules L<Array::Base> and L<String::Base> can now be used to |
240
|
|
|
|
|
|
|
replace this functionality. |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
=head2 /\C/ |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
The C<\C> regular expression character class would match a single byte of the |
245
|
|
|
|
|
|
|
internal representation of the string, which was dangerous because it violated |
246
|
|
|
|
|
|
|
the logical character abstraction of Perl strings, and substitutions using it |
247
|
|
|
|
|
|
|
could result in malformed UTF-8 sequences. It was deprecated in perl v5.20.0 |
248
|
|
|
|
|
|
|
and removed in perl v5.24.0. Instead, explicitly encode the string to UTF-8 |
249
|
|
|
|
|
|
|
using L<Encode> to examine its UTF-8-encoded byte representation. |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
=head2 ?PATTERN? |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
The C<?PATTERN?> regex match syntax is deprecated in perl v5.14.0 and removed |
254
|
|
|
|
|
|
|
in perl v5.22.0. Use C<m?PATTERN?> instead. |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
=head2 autoderef |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
An experimental feature was introduced in perl v5.14.0 to allow calling various |
259
|
|
|
|
|
|
|
builtin functions (which operate on arrays or hashes) on a reference, which |
260
|
|
|
|
|
|
|
would automatically dereference the operand. This led to ambiguity when passed |
261
|
|
|
|
|
|
|
objects that overload both array and hash dereferencing, and so was removed in |
262
|
|
|
|
|
|
|
perl v5.24.0. Instead, explicitly dereference the reference when calling these |
263
|
|
|
|
|
|
|
functions. The functions affected are C<each>, C<keys>, C<pop>, C<push>, |
264
|
|
|
|
|
|
|
C<shift>, C<splice>, C<unshift>, and C<values>. |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
=head2 Bare here-doc |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
Using C< << > to initiate a here-doc would create it with an empty terminator, |
269
|
|
|
|
|
|
|
similar to C< <<'' >, so the here-doc would terminate on the next empty line. |
270
|
|
|
|
|
|
|
Omitting the quoted empty string has been deprecated since perl 5, and is a |
271
|
|
|
|
|
|
|
fatal error in perl v5.28.0. |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
=head2 chdir('') |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
Passing an empty string or C<undef> to C<chdir()> would change to the home |
276
|
|
|
|
|
|
|
directory, but this usage is deprecated in perl v5.8.0 and throws an error in |
277
|
|
|
|
|
|
|
perl v5.24.0. Instead, call C<chdir()> with no arguments for this behavior. |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
=head2 defined on array/hash |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
Using the function C<defined()> on an array or hash probably does not do what |
282
|
|
|
|
|
|
|
you expected, and is deprecated in perl v5.6.2 and throws a fatal error in perl |
283
|
|
|
|
|
|
|
v5.22.0. To check if an array or hash is non-empty, test if it has elements. |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
if (@foo) { ... } |
286
|
|
|
|
|
|
|
if (keys %bar) { ... } |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
=head2 do SUBROUTINE(LIST) |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
This form of C<do> to call a subroutine has been deprecated since perl 5, and |
291
|
|
|
|
|
|
|
is removed in perl v5.20.0. |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
=head2 NBSP in \N{...} |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
Use of the "no-break space" character in L<character names|charnames> is |
296
|
|
|
|
|
|
|
deprecated in perl v5.22.0 and an error in perl v5.26.0. |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
=head2 POSIX character functions |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
Several character matching functions in L<POSIX>.pm are deprecated in perl |
301
|
|
|
|
|
|
|
v5.20.0. See the L<POSIX> documentation for more details. Most uses of these |
302
|
|
|
|
|
|
|
functions can be replaced with appropriate regex matches. |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
isalnum, isalpha, iscntrl, isdigit, isgraph, islower, isprint, ispunct, isspace, issuper, isxdigit |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
=head2 POSIX::tmpnam() |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
The C<tmpnam()> function from L<POSIX>.pm is deprecated in perl v5.22.0 and |
309
|
|
|
|
|
|
|
removed in perl v5.26.0. Use L<File::Temp> instead. |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
=head2 qw(...) as parentheses |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
Literal parentheses are required for certain statements such as a |
314
|
|
|
|
|
|
|
C<for my $foo (...) { ... }> construct. Using a C<qw(...)> list literal without |
315
|
|
|
|
|
|
|
surrounding parentheses in this syntax is deprecated in perl v5.14.0 and a |
316
|
|
|
|
|
|
|
syntax error in perl v5.18.0. Wrap the literal in parentheses: |
317
|
|
|
|
|
|
|
C<for my $foo (qw(...)) { ... }>. |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
=head2 require ::Foo::Bar |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
A bareword C<require> (or C<use>) starting with a double colon would |
322
|
|
|
|
|
|
|
inadvertently translate to a path starting with C</>. Starting in perl v5.26.0, |
323
|
|
|
|
|
|
|
this is a fatal error. |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
=head2 UNIVERSAL->import() |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
The method C<< UNIVERSAL->import() >> and similarly passing import arguments to |
328
|
|
|
|
|
|
|
C<use UNIVERSAL> is deprecated in perl v5.12.0 and throws a fatal error in perl |
329
|
|
|
|
|
|
|
v5.22.0. Calling C<use UNIVERSAL> with no arguments is not an error, but serves |
330
|
|
|
|
|
|
|
no purpose. |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
=head1 AFFILIATION |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
This policy is part of L<Perl::Critic::Community>. |
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
=head1 CONFIGURATION |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
This policy is not configurable except for the standard options. |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
=head1 CAVEATS |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
This policy is incomplete, as many deprecations are difficult to test for |
343
|
|
|
|
|
|
|
statically. It is recommended to use L<perlbrew> or L<perl-build> to test your |
344
|
|
|
|
|
|
|
code under newer versions of Perl, with C<warnings> enabled. |
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
=head1 AUTHOR |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
Dan Book, C<dbook@cpan.org> |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
Copyright 2015, Dan Book. |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
This library is free software; you may redistribute it and/or modify it under |
355
|
|
|
|
|
|
|
the terms of the Artistic License version 2.0. |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
=head1 SEE ALSO |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
L<Perl::Critic> |