File Coverage

blib/lib/Perl/Critic/Policy/InputOutput/RequireBracedFileHandleWithPrint.pm
Criterion Covered Total %
statement 38 44 86.3
branch 14 30 46.6
condition 4 6 66.6
subroutine 11 11 100.0
pod 4 5 80.0
total 71 96 73.9


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::InputOutput::RequireBracedFileHandleWithPrint;
2              
3 40     40   25189 use 5.010001;
  40         155  
4 40     40   183 use strict;
  40         79  
  40         836  
5 40     40   143 use warnings;
  40         64  
  40         1444  
6 40     40   173 use Readonly;
  40         112  
  40         2130  
7              
8 40     40   210 use Perl::Critic::Utils qw{ :severities :classification :data_conversion };
  40         69  
  40         1987  
9 40     40   13243 use parent 'Perl::Critic::Policy';
  40         118  
  40         266  
10              
11             our $VERSION = '1.156';
12              
13             #-----------------------------------------------------------------------------
14              
15             Readonly::Array my @POSTFIX_WORDS => qw( if unless for );
16             Readonly::Hash my %POSTFIX_WORDS => hashify( @POSTFIX_WORDS );
17             Readonly::Scalar my $PRINT_RX => qr/ \A (?: print f? | say ) \z /xms;
18              
19             Readonly::Scalar my $DESC => q{File handle for "print" or "printf" is not braced};
20             Readonly::Scalar my $EXPL => [ 217 ];
21              
22             #-----------------------------------------------------------------------------
23              
24 90     90 0 611 sub supported_parameters { return () }
25 75     75 1 240 sub default_severity { return $SEVERITY_LOWEST }
26 84     84 1 266 sub default_themes { return qw( core pbp cosmetic ) }
27 31     31 1 66 sub applies_to { return 'PPI::Token::Word' }
28              
29             #-----------------------------------------------------------------------------
30              
31             sub violates {
32 332     332 1 521 my ( $self, $elem, undef ) = @_;
33              
34 332 100       815 return if $elem !~ $PRINT_RX;
35 3 50       25 return if ! is_function_call($elem);
36              
37 3         5 my @sib;
38              
39 3         10 $sib[0] = $elem->snext_sibling();
40 3 50       50 return if !$sib[0];
41              
42             # Deal with situations where 'print' is called with parentheses
43 3 50       26 if ( $sib[0]->isa('PPI::Structure::List') ) {
44 0         0 my $expr = $sib[0]->schild(0);
45 0 0       0 return if !$expr;
46 0         0 $sib[0] = $expr->schild(0);
47 0 0       0 return if !$sib[0];
48             }
49              
50 3         17 $sib[1] = $sib[0]->next_sibling();
51 3 50       55 return if !$sib[1];
52 3         33 $sib[2] = $sib[1]->next_sibling();
53 3 50       59 return if !$sib[2];
54              
55             # First token must be a scalar symbol or bareword;
56 3 50 66     23 return if !( ($sib[0]->isa('PPI::Token::Symbol') && $sib[0] =~ m/\A \$/xms)
      66        
57             || $sib[0]->isa('PPI::Token::Word') );
58              
59             # First token must not be a builtin function or control
60 3 50       21 return if is_perl_builtin($sib[0]);
61 3 50       33 return if exists $POSTFIX_WORDS{ $sib[0] };
62              
63             # Second token must be white space
64 3 100       38 return if !$sib[1]->isa('PPI::Token::Whitespace');
65              
66             # Third token must not be an operator
67 2 50       8 return if $sib[2]->isa('PPI::Token::Operator');
68              
69             # Special case for postfix controls
70 2 50       4 return if exists $POSTFIX_WORDS{ $sib[2] };
71              
72 0 0         return if $sib[0]->isa('PPI::Structure::Block');
73              
74 0           return $self->violation( $DESC, $EXPL, $elem );
75             }
76              
77             1;
78              
79             __END__
80              
81             #-----------------------------------------------------------------------------
82              
83             =pod
84              
85             =head1 NAME
86              
87             Perl::Critic::Policy::InputOutput::RequireBracedFileHandleWithPrint - Write C<print {$FH} $foo, $bar;> instead of C<print $FH $foo, $bar;>.
88              
89             =head1 AFFILIATION
90              
91             This Policy is part of the core L<Perl::Critic|Perl::Critic>
92             distribution.
93              
94              
95             =head1 DESCRIPTION
96              
97             The C<print> and C<printf> functions have a unique syntax that
98             supports an optional file handle argument. Conway suggests wrapping
99             this argument in braces to make it visually stand out from the other
100             arguments. When you put braces around any of the special
101             package-level file handles like C<STDOUT>, C<STDERR>, and C<DATA>, you
102             must add the C<'*'> sigil or else it won't compile under C<use strict
103             'subs'>.
104              
105             print $FH "Mary had a little lamb\n"; #not ok
106             print {$FH} "Mary had a little lamb\n"; #ok
107              
108             print STDERR $foo, $bar, $baz; #not ok
109             print {STDERR} $foo, $bar, $baz; #won't compile under 'strict'
110             print {*STDERR} $foo, $bar, $baz; #perfect!
111              
112              
113             =head1 CONFIGURATION
114              
115             This Policy is not configurable except for the standard options.
116              
117              
118             =head1 AUTHOR
119              
120             Jeffrey Ryan Thalhammer <jeff@imaginative-software.com>
121              
122             =head1 COPYRIGHT
123              
124             Copyright (c) 2005-2011 Imaginative Software Systems. All rights reserved.
125              
126             This program is free software; you can redistribute it and/or modify
127             it under the same terms as Perl itself. The full text of this license
128             can be found in the LICENSE file included with this module.
129              
130             =cut
131              
132             # Local Variables:
133             # mode: cperl
134             # cperl-indent-level: 4
135             # fill-column: 78
136             # indent-tabs-mode: nil
137             # c-indentation-style: bsd
138             # End:
139             # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :