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   26605 use 5.010001;
  40         166  
4 40     40   260 use strict;
  40         125  
  40         878  
5 40     40   238 use warnings;
  40         105  
  40         1058  
6 40     40   281 use Readonly;
  40         142  
  40         2193  
7              
8 40     40   296 use Perl::Critic::Utils qw{ :severities :classification :ppi };
  40         116  
  40         2175  
9 40     40   15469 use parent 'Perl::Critic::Policy';
  40         156  
  40         239  
10              
11             our $VERSION = '1.148';
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 1675 sub supported_parameters { return () }
21 90     90 1 424 sub default_severity { return $SEVERITY_HIGHEST }
22 92     92 1 414 sub default_themes { return qw( core pbp bugs certrec ) }
23 44     44 1 165 sub applies_to { return 'PPI::Token::Word' }
24              
25             #-----------------------------------------------------------------------------
26              
27             sub violates {
28 428     428 1 903 my ($self, $elem, undef) = @_;
29              
30 428 100       937 return if $elem->content() ne 'opendir';
31 34 100       189 return if ! is_function_call($elem);
32              
33 33         89 my $first_arg = ( parse_arg_list($elem) )[0];
34 33 100       136 return if !$first_arg;
35 32         63 my $token = $first_arg->[0];
36 32 50       91 return if !$token;
37              
38 32 100 100     133 if ( $token->isa('PPI::Token::Word') && $token eq 'local' ) { # handle local *DH
39 8         107 $token = $first_arg->[1]; # the token that follows local in the first argument
40 8 50       47 return if !$token;
41             }
42 32 100 66     281 if ( $token->isa('PPI::Token::Cast') && $token eq q{\\} ) { # handle \*DH
43 4         54 $token = $first_arg->[1]; # the token that follows \ in the first argument
44 4 50       16 return if !$token;
45             }
46              
47 32 100       114 if ( $token->isa('PPI::Token::Symbol') ) {
    50          
48 20 100       49 return $self->violation($DESC, $EXPL, $elem) if $token =~ m/^[*]/xms;
49             } elsif ( $token->isa('PPI::Token::Word') ) {
50 12 100       30 return $self->violation($DESC, $EXPL, $elem) if $token !~ m/^(?:my|our)$/xms;
51             }
52              
53 16         141 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 :