File Coverage

blib/lib/Perl/Critic/Policy/InputOutput/ProhibitBacktickOperators.pm
Criterion Covered Total %
statement 21 26 80.7
branch 0 4 0.0
condition n/a
subroutine 10 11 90.9
pod 4 5 80.0
total 35 46 76.0


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::InputOutput::ProhibitBacktickOperators;
2              
3 40     40   26942 use 5.010001;
  40         178  
4 40     40   8153 use strict;
  40         182  
  40         1041  
5 40     40   272 use warnings;
  40         125  
  40         956  
6 40     40   256 use Readonly;
  40         116  
  40         1976  
7              
8 40     40   268 use Perl::Critic::Utils qw{ :severities is_in_void_context };
  40         119  
  40         1912  
9              
10 40     40   5285 use parent 'Perl::Critic::Policy';
  40         151  
  40         255  
11              
12             our $VERSION = '1.150';
13              
14             #-----------------------------------------------------------------------------
15              
16             Readonly::Scalar my $EXPL => q{Use IPC::Open3 instead};
17             Readonly::Scalar my $DESC => q{Backtick operator used};
18              
19             Readonly::Scalar my $VOID_EXPL => q{Assign result to a variable or use system() instead};
20             Readonly::Scalar my $VOID_DESC => q{Backtick operator used in void context};
21              
22             #-----------------------------------------------------------------------------
23              
24             sub supported_parameters {
25             return (
26             {
27 90     90 0 1862 name => 'only_in_void_context',
28             description => 'Allow backticks everywhere except in void contexts.',
29             behavior => 'boolean',
30             },
31             );
32             }
33              
34 74     74 1 296 sub default_severity { return $SEVERITY_MEDIUM }
35 74     74 1 347 sub default_themes { return qw(core maintenance) }
36 30     30 1 106 sub applies_to { return qw(PPI::Token::QuoteLike::Backtick
37             PPI::Token::QuoteLike::Command ) }
38              
39             #-----------------------------------------------------------------------------
40              
41             sub violates {
42 0     0 1   my ( $self, $elem, undef ) = @_;
43              
44 0 0         if ( $self->{_only_in_void_context} ) {
45 0 0         return if not is_in_void_context( $elem );
46              
47 0           return $self->violation( $VOID_DESC, $VOID_EXPL, $elem );
48             }
49              
50 0           return $self->violation( $DESC, $EXPL, $elem );
51             }
52              
53             1;
54              
55             __END__
56              
57             #-----------------------------------------------------------------------------
58              
59             =pod
60              
61             =for stopwords perlipc
62              
63             =head1 NAME
64              
65             Perl::Critic::Policy::InputOutput::ProhibitBacktickOperators - Discourage stuff like C<@files = `ls $directory`>.
66              
67             =head1 AFFILIATION
68              
69             This Policy is part of the core L<Perl::Critic|Perl::Critic>
70             distribution.
71              
72              
73             =head1 DESCRIPTION
74              
75             Backticks are super-convenient, especially for CGI programs, but I
76             find that they make a lot of noise by filling up STDERR with messages
77             when they fail. I think its better to use IPC::Open3 to trap all the
78             output and let the application decide what to do with it.
79              
80             use IPC::Open3 'open3';
81             $SIG{CHLD} = 'IGNORE';
82              
83             @output = `some_command`; #not ok
84              
85             my ($writer, $reader, $err);
86             open3($writer, $reader, $err, 'some_command'); #ok;
87             @output = <$reader>; #Output here
88             @errors = <$err>; #Errors here, instead of the console
89              
90              
91             =head1 CONFIGURATION
92              
93             Alternatively, if you do want to use backticks, you can restrict
94             checks to void contexts by adding the following to your
95             F<.perlcriticrc> file:
96              
97             [InputOutput::ProhibitBacktickOperators]
98             only_in_void_context = 1
99              
100             The purpose of backticks is to capture the output of an external
101             command. Use of them in a void context is likely a bug. If the
102             output isn't actually required, C<system()> should be used. Otherwise
103             assign the result to a variable.
104              
105             `some_command`; #not ok
106             $output = `some_command`; #ok
107             @output = `some_command`; #ok
108              
109              
110             =head1 NOTES
111              
112             This policy also prohibits the generalized form of backticks seen as
113             C<qx{}>.
114              
115             See L<perlipc|perlipc> for more discussion on using C<wait()> instead
116             of C<$SIG{CHLD} = 'IGNORE'>.
117              
118             You might consider using the C<capture()> function from the
119             L<IPC::System::Simple|IPC::System::Simple> module for a safer way of
120             doing what backticks do, especially on Windows. The module also has a
121             safe wrapper around C<system()>.
122              
123              
124             =head1 AUTHOR
125              
126             Jeffrey Ryan Thalhammer <jeff@imaginative-software.com>
127              
128              
129             =head1 COPYRIGHT
130              
131             Copyright (c) 2005-2011 Imaginative Software Systems. All rights reserved.
132              
133             This program is free software; you can redistribute it and/or modify
134             it under the same terms as Perl itself. The full text of this license
135             can be found in the LICENSE file included with this module.
136              
137             =cut
138              
139             # Local Variables:
140             # mode: cperl
141             # cperl-indent-level: 4
142             # fill-column: 78
143             # indent-tabs-mode: nil
144             # c-indentation-style: bsd
145             # End:
146             # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :