File Coverage

blib/lib/Perl/Critic/Policy/InputOutput/ProhibitBarewordFileHandles.pm
Criterion Covered Total %
statement 23 36 63.8
branch 1 16 6.2
condition 0 3 0.0
subroutine 11 11 100.0
pod 4 5 80.0
total 39 71 54.9


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::InputOutput::ProhibitBarewordFileHandles;
2              
3 40     40   24151 use 5.010001;
  40         138  
4 40     40   190 use strict;
  40         93  
  40         720  
5 40     40   140 use warnings;
  40         84  
  40         1409  
6 40     40   155 use Readonly;
  40         67  
  40         1973  
7              
8 40     40   197 use Perl::Critic::Utils qw{ :severities :classification :ppi hashify };
  40         96  
  40         2012  
9 40     40   12121 use parent 'Perl::Critic::Policy';
  40         117  
  40         238  
10              
11             our $VERSION = '1.156';
12              
13             #-----------------------------------------------------------------------------
14              
15             Readonly::Scalar my $DESC => q{Bareword file handle opened};
16             Readonly::Scalar my $EXPL => [ 202, 204 ];
17              
18             #-----------------------------------------------------------------------------
19              
20 90     90 0 549 sub supported_parameters { return () }
21 75     75 1 231 sub default_severity { return $SEVERITY_HIGHEST }
22 92     92 1 303 sub default_themes { return qw( core pbp bugs certrec ) }
23 37     37 1 85 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 361     361 1 543 my ($self, $elem, undef) = @_;
32              
33 361 50       542 return if ! $OPEN_FUNCS{$elem->content()};
34 0 0         return if ! is_function_call($elem);
35              
36 0           my $first_arg = ( parse_arg_list($elem) )[0];
37 0 0         return if !$first_arg;
38 0           my $first_token;
39             # PPI can mis-parse something like open( CHECK, ... ) as a scheduled
40             # block. So ...
41 0 0         if ( 'PPI::Statement::Scheduled' eq ref $first_arg ) {
    0          
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           $first_token = $first_arg->schild( 0 );
46             } elsif ( $ARRAY_REF eq ref $first_arg ) {
47             # This is the normal path through the code.
48 0           $first_token = $first_arg->[0];
49             } else {
50             # This is purely defensive.
51 0           return;
52             }
53 0 0         return if !$first_token;
54              
55 0 0         if ( $first_token->isa('PPI::Token::Word') ) {
56 0 0 0       if ( ($first_token ne 'my') && ($first_token !~ m/^STD(?:IN|OUT|ERR)$/xms ) ) {
57 0           return $self->violation( $DESC, $EXPL, $elem );
58             }
59             }
60 0           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 :