File Coverage

blib/lib/Perl/Critic/Policy/InputOutput/ProhibitBarewordFileHandles.pm
Criterion Covered Total %
statement 34 36 94.4
branch 13 16 81.2
condition 3 3 100.0
subroutine 11 11 100.0
pod 4 5 80.0
total 65 71 91.5


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::InputOutput::ProhibitBarewordFileHandles;
2              
3 40     40   27290 use 5.010001;
  40         176  
4 40     40   271 use strict;
  40         138  
  40         832  
5 40     40   246 use warnings;
  40         123  
  40         1063  
6 40     40   237 use Readonly;
  40         123  
  40         2238  
7              
8 40     40   298 use Perl::Critic::Utils qw{ :severities :classification :ppi hashify };
  40         105  
  40         2194  
9 40     40   15816 use parent 'Perl::Critic::Policy';
  40         114  
  40         262  
10              
11             our $VERSION = '1.146';
12              
13             #-----------------------------------------------------------------------------
14              
15             Readonly::Scalar my $DESC => q{Bareword file handle opened};
16             Readonly::Scalar my $EXPL => [ 202, 204 ];
17              
18             #-----------------------------------------------------------------------------
19              
20 93     93 0 1681 sub supported_parameters { return () }
21 85     85 1 388 sub default_severity { return $SEVERITY_HIGHEST }
22 92     92 1 399 sub default_themes { return qw( core pbp bugs certrec ) }
23 40     40 1 162 sub applies_to { return 'PPI::Token::Word' }
24              
25             #-----------------------------------------------------------------------------
26              
27             Readonly::Scalar my $ARRAY_REF => ref [];
28             Readonly::Hash my %OPEN_FUNCS => hashify( qw( open sysopen ) );
29              
30             sub violates {
31 432     432 1 839 my ($self, $elem, undef) = @_;
32              
33 432 100       937 return if ! $OPEN_FUNCS{$elem->content()};
34 28 100       344 return if ! is_function_call($elem);
35              
36 27         73 my $first_arg = ( parse_arg_list($elem) )[0];
37 27 100       91 return if !$first_arg;
38 26         45 my $first_token;
39             # PPI can mis-parse something like open( CHECK, ... ) as a scheduled
40             # block. So ...
41 26 50       107 if ( 'PPI::Statement::Scheduled' eq ref $first_arg ) {
    50          
42             # If PPI PR #247 is accepted, the following should be unnecessary.
43             # We get here because when parse_arg_list() gets confused it
44             # just returns the statement object.
45 0         0 $first_token = $first_arg->schild( 0 );
46             } elsif ( $ARRAY_REF eq ref $first_arg ) {
47             # This is the normal path through the code.
48 26         56 $first_token = $first_arg->[0];
49             } else {
50             # This is purely defensive.
51 0         0 return;
52             }
53 26 50       85 return if !$first_token;
54              
55 26 100       93 if ( $first_token->isa('PPI::Token::Word') ) {
56 22 100 100     66 if ( ($first_token ne 'my') && ($first_token !~ m/^STD(?:IN|OUT|ERR)$/xms ) ) {
57 11         239 return $self->violation( $DESC, $EXPL, $elem );
58             }
59             }
60 15         225 return; #ok!
61             }
62              
63             1;
64              
65             __END__
66              
67             #-----------------------------------------------------------------------------
68              
69             =pod
70              
71             =head1 NAME
72              
73             Perl::Critic::Policy::InputOutput::ProhibitBarewordFileHandles - Write C<open my $fh, q{<}, $filename;> instead of C<open FH, q{<}, $filename;>.
74              
75             =head1 AFFILIATION
76              
77             This Policy is part of the core L<Perl::Critic|Perl::Critic>
78             distribution.
79              
80              
81             =head1 DESCRIPTION
82              
83             Using bareword symbols to refer to file handles is particularly evil
84             because they are global, and you have no idea if that symbol already
85             points to some other file handle. You can mitigate some of that risk
86             by C<local>izing the symbol first, but that's pretty ugly. Since Perl
87             5.6, you can use an undefined scalar variable as a lexical reference
88             to an anonymous filehandle. Alternatively, see the
89             L<IO::Handle|IO::Handle> or L<IO::File|IO::File> or
90             L<FileHandle|FileHandle> modules for an object-oriented approach.
91              
92             open FH, '<', $some_file; #not ok
93             open my $fh, '<', $some_file; #ok
94             my $fh = IO::File->new($some_file); #ok
95              
96             There are three exceptions: STDIN, STDOUT and STDERR. These three
97             standard filehandles are always package variables.
98              
99             This policy also applies to the C<sysopen> function as well.
100              
101              
102             =head1 CONFIGURATION
103              
104             This Policy is not configurable except for the standard options.
105              
106              
107             =head1 SEE ALSO
108              
109             L<IO::Handle|IO::Handle>
110              
111             L<IO::File|IO::File>
112              
113             =head1 AUTHOR
114              
115             Jeffrey Ryan Thalhammer <jeff@imaginative-software.com>
116              
117             =head1 COPYRIGHT
118              
119             Copyright (c) 2005-2022 Imaginative Software Systems. All rights reserved.
120              
121             This program is free software; you can redistribute it and/or modify
122             it under the same terms as Perl itself.
123              
124             =cut
125              
126             # Local Variables:
127             # mode: cperl
128             # cperl-indent-level: 4
129             # fill-column: 78
130             # indent-tabs-mode: nil
131             # c-indentation-style: bsd
132             # End:
133             # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :