File: BarewordFilehandles.pm

package info (click to toggle)
libperl-critic-community-perl 1.0.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 428 kB
  • sloc: perl: 1,100; makefile: 2
file content (99 lines) | stat: -rw-r--r-- 2,526 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package Perl::Critic::Policy::Community::BarewordFilehandles;

use strict;
use warnings;

use Perl::Critic::Utils qw(:severities :classification :ppi);
use parent 'Perl::Critic::Policy';

our $VERSION = 'v1.0.4';

use constant DESC => 'Using bareword filehandles';
use constant EXPL => 'Bareword filehandles are a legacy feature, creating the filehandles as package variables. Use lexical, scoped filehandles instead (open my $fh, ...).';

sub supported_parameters { () }
sub default_severity { $SEVERITY_HIGH }
sub default_themes { 'community' }
sub applies_to { 'PPI::Token::Word' }

my %openers = (
	accept     => 1,
	open       => 1,
	opendir    => 1,
	pipe       => 2,
	socket     => 1,
	socketpair => 2,
);

my %builtins = (
	ARGV    => 1,
	ARGVOUT => 1,
	DATA    => 1,
	STDERR  => 1,
	STDIN   => 1,
	STDOUT  => 1,
);

sub violates {
	my ($self, $elem) = @_;
	return () unless exists $openers{$elem} and is_function_call $elem;
	my $num_handles = $openers{$elem};
	
	my @args = parse_arg_list $elem;
	my @handles = splice @args, 0, $num_handles;
	
	my @violations;
	foreach my $handle (@handles) {
		my $name = pop @$handle // next;
		push @violations, $self->violation(DESC, EXPL, $elem)
			if $name->isa('PPI::Token::Word') and !exists $builtins{$name};
	}
	
	return @violations;
}

1;

=head1 NAME

Perl::Critic::Policy::Community::BarewordFilehandles - Don't use bareword
filehandles other than built-ins

=head1 DESCRIPTION

Bareword filehandles are allowed in C<open()> as a legacy feature, but will use
a global package variable. Instead, use a lexical variable with C<my> so that
the filehandle is scoped to the current block, and will be automatically closed
when it goes out of scope. Built-in bareword filehandles like C<STDOUT> and
C<DATA> are ok.

  open FH, '<', $filename;     # not ok
  open my $fh, '<', $filename; # ok

This policy is similar to the core policy
L<Perl::Critic::Policy::InputOutput::ProhibitBarewordFileHandles>, but allows
more combinations of built-in bareword handles and filehandle-opening functions
such as C<pipe> and C<socketpair>.

=head1 AFFILIATION

This policy is part of L<Perl::Critic::Community>.

=head1 CONFIGURATION

This policy is not configurable except for the standard options.

=head1 AUTHOR

Dan Book, C<dbook@cpan.org>

=head1 COPYRIGHT AND LICENSE

Copyright 2015, Dan Book.

This library is free software; you may redistribute it and/or modify it under
the terms of the Artistic License version 2.0.

=head1 SEE ALSO

L<Perl::Critic>, L<bareword::filehandles>