File Coverage

blib/lib/Perl/Critic/Policy/InputOutput/ProhibitBarewordDirHandles.pm
Criterion Covered Total %
statement 38 38 100.0
branch 20 24 83.3
condition 5 6 83.3
subroutine 11 11 100.0
pod 4 5 80.0
total 78 84 92.8


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::InputOutput::ProhibitBarewordDirHandles;
2              
3 40     40   27073 use 5.010001;
  40         172  
4 40     40   267 use strict;
  40         120  
  40         1034  
5 40     40   238 use warnings;
  40         128  
  40         1187  
6 40     40   240 use Readonly;
  40         134  
  40         2472  
7              
8 40     40   344 use Perl::Critic::Utils qw{ :severities :classification :ppi };
  40         130  
  40         2383  
9 40     40   15633 use parent 'Perl::Critic::Policy';
  40         106  
  40         262  
10              
11             our $VERSION = '1.146';
12              
13             #-----------------------------------------------------------------------------
14              
15             Readonly::Scalar my $DESC => q{Bareword dir handle opened};
16             Readonly::Scalar my $EXPL => [ 202, 204 ];
17              
18             #-----------------------------------------------------------------------------
19              
20 97     97 0 1677 sub supported_parameters { return () }
21 90     90 1 437 sub default_severity { return $SEVERITY_HIGHEST }
22 92     92 1 434 sub default_themes { return qw( core pbp bugs certrec ) }
23 44     44 1 175 sub applies_to { return 'PPI::Token::Word' }
24              
25             #-----------------------------------------------------------------------------
26              
27             sub violates {
28 428     428 1 897 my ($self, $elem, undef) = @_;
29              
30 428 100       884 return if $elem->content() ne 'opendir';
31 34 100       202 return if ! is_function_call($elem);
32              
33 33         108 my $first_arg = ( parse_arg_list($elem) )[0];
34 33 100       101 return if !$first_arg;
35 32         62 my $token = $first_arg->[0];
36 32 50       101 return if !$token;
37              
38 32 100 100     135 if ( $token->isa('PPI::Token::Word') && $token eq 'local' ) { # handle local *DH
39 8         109 $token = $first_arg->[1]; # the token that follows local in the first argument
40 8 50       26 return if !$token;
41             }
42 32 100 66     298 if ( $token->isa('PPI::Token::Cast') && $token eq q{\\} ) { # handle \*DH
43 4         59 $token = $first_arg->[1]; # the token that follows \ in the first argument
44 4 50       12 return if !$token;
45             }
46              
47 32 100       140 if ( $token->isa('PPI::Token::Symbol') ) {
    50          
48 20 100       47 return $self->violation($DESC, $EXPL, $elem) if $token =~ m/^[*]/xms;
49             } elsif ( $token->isa('PPI::Token::Word') ) {
50 12 100       29 return $self->violation($DESC, $EXPL, $elem) if $token !~ m/^(?:my|our)$/xms;
51             }
52              
53 16         143 return; #ok!
54             }
55              
56             1;
57              
58             __END__
59              
60             #-----------------------------------------------------------------------------
61              
62             =pod
63              
64             =head1 NAME
65              
66             Perl::Critic::Policy::InputOutput::ProhibitBarewordDirHandles - Write C<opendir my $dh, $dirname;> instead of C<opendir DH, $dirname;>.
67              
68             =head1 AFFILIATION
69              
70             This Policy is part of the core L<Perl::Critic|Perl::Critic>
71             distribution.
72              
73              
74             =head1 DESCRIPTION
75              
76             Using bareword symbols to refer to directory handles is particularly evil
77             because they are global, and you have no idea if that symbol already
78             points to some other file or directory handle. You can mitigate some of that risk
79             by C<local>izing the symbol first, but that's pretty ugly. Since Perl
80             5.6, you can use an undefined scalar variable as a lexical reference
81             to an anonymous file handle or directory handle. Alternatively, see the
82             L<IO::Handle|IO::Handle> or L<IO::Dir|IO::Dir>
83             modules for an object-oriented approach.
84              
85             opendir DH, $some_dir; #not ok
86             opendir *DH, $some_dir; #not ok
87             opendir \*DH, $some_dir; #not ok
88             opendir local *DH, $some_dir; #not ok
89             opendir $dh, $some_dir; #ok
90             opendir my $dh, $some_dir; #ok
91             opendir our $dh, $some_dir; #ok
92             opendir local $dh, $some_dir; #ok
93             my $dh = IO::Dir->new($some_dir); #ok
94              
95             And Perl7 will probably drop support for bareword filehandles.
96              
97             =head1 CONFIGURATION
98              
99             This Policy is not configurable except for the standard options.
100              
101             =head1 SEE ALSO
102              
103             L<Perl::Critic::Policy::InputOutput::ProhibitBarewordFileHandles::Perl::Critic::Policy::InputOutput::ProhibitBarewordFileHandles>
104              
105             L<IO::Handle|IO::Handle>
106              
107             L<IO::Dir|IO::Dir>
108              
109             =head1 AUTHOR
110              
111             Jeffrey Ryan Thalhammer <jeff@imaginative-software.com>,
112             C<github.com/pali>, C<github.com/raforg>
113              
114             =head1 COPYRIGHT
115              
116             Copyright (c) 2005-2011, 2021 Imaginative Software Systems. All rights reserved.
117              
118             This program is free software; you can redistribute it and/or modify
119             it under the same terms as Perl itself.
120              
121             =cut
122              
123             # Local Variables:
124             # mode: cperl
125             # cperl-indent-level: 4
126             # fill-column: 78
127             # indent-tabs-mode: nil
128             # c-indentation-style: bsd
129             # End:
130             # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :