File Coverage

blib/lib/Perl/Critic/Policy/Community/Prototypes.pm
Criterion Covered Total %
statement 36 37 97.3
branch 12 14 85.7
condition 15 19 78.9
subroutine 10 11 90.9
pod 4 5 80.0
total 77 86 89.5


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::Community::Prototypes;
2              
3 1     1   444 use strict;
  1         2  
  1         29  
4 1     1   5 use warnings;
  1         2  
  1         27  
5              
6 1     1   5 use Perl::Critic::Utils qw(:severities :classification :ppi);
  1         2  
  1         63  
7 1     1   382 use parent 'Perl::Critic::Policy';
  1         2  
  1         7  
8              
9             our $VERSION = 'v1.0.2';
10              
11 1     1   86 use constant DESC => 'Using function prototypes';
  1         2  
  1         73  
12 1     1   7 use constant EXPL => 'Function prototypes (sub foo ($@) { ... }) will usually not do what you want. Omit the prototype, or use signatures instead.';
  1         2  
  1         420  
13              
14             sub supported_parameters {
15             (
16             {
17 9     9 0 39570 name => 'signature_enablers',
18             description => 'Non-standard modules to recognize as enabling signatures',
19             behavior => 'string list',
20             },
21             )
22             }
23              
24 1     1 1 14 sub default_severity { $SEVERITY_MEDIUM }
25 0     0 1 0 sub default_themes { 'community' }
26 9     9 1 69520 sub applies_to { 'PPI::Document' }
27              
28             sub violates {
29 9     9 1 106 my ($self, $elem) = @_;
30              
31             # Check if signatures are enabled
32 9   100     26 my $includes = $elem->find('PPI::Statement::Include') || [];
33 9         134 foreach my $include (@$includes) {
34 5 50       20 next unless $include->type eq 'use';
35 5 100 66     134 return () if $include->pragma eq 'feature' and $include =~ m/\bsignatures\b/;
36 4 100 66     124 return () if $include->pragma eq 'experimental' and $include =~ m/\bsignatures\b/;
37 3 100 66     97 return () if $include->module eq 'Mojo::Base' and $include =~ m/-signatures\b/;
38 2 100 66     47 return () if $include->module eq 'Mojolicious::Lite' and $include =~ m/-signatures\b/;
39 1 50       24 return () if exists $self->{_signature_enablers}{$include->module};
40             }
41            
42 4   100     13 my $prototypes = $elem->find('PPI::Token::Prototype') || [];
43 4         45 my @violations;
44 4         11 foreach my $prototype (@$prototypes) {
45             # Empty prototypes and prototypes containing & can be useful
46 3 100 100     13 next if $prototype->prototype eq '' or $prototype->prototype =~ /&/;
47 1         40 push @violations, $self->violation(DESC, EXPL, $prototype);
48             }
49            
50 4         320 return @violations;
51             }
52              
53             1;
54              
55             =head1 NAME
56              
57             Perl::Critic::Policy::Community::Prototypes - Don't use function prototypes
58              
59             =head1 DESCRIPTION
60              
61             Function prototypes are primarily a hint to the Perl parser for parsing the
62             function's argument list. They are not a way to validate or count the arguments
63             passed to the function, and will cause confusion if used this way. Often, the
64             prototype can simply be left out, but see L<perlsub/"Signatures"> for a more
65             modern method of declaring arguments.
66              
67             sub foo ($$) { ... } # not ok
68             sub foo { ... } # ok
69             use feature 'signatures'; sub foo ($bar, $baz) { ... } # ok
70             use experimental 'signatures'; sub foo ($bar, $baz) { ... } # ok
71              
72             This policy is similar to the core policy
73             L<Perl::Critic::Policy::Subroutines::ProhibitSubroutinePrototypes>, but
74             additionally ignores files using the C<signatures> feature, and allows empty
75             prototypes and prototypes containing C<&>, as these are often useful for
76             structural behavior.
77              
78             =head1 AFFILIATION
79              
80             This policy is part of L<Perl::Critic::Community>.
81              
82             =head1 CONFIGURATION
83              
84             This policy can be configured to recognize additional modules as enabling the
85             C<signatures> feature, by putting an entry in a C<.perlcriticrc> file like
86             this:
87              
88             [Community::Prototypes]
89             signature_enablers = MyApp::Base
90              
91             =head1 AUTHOR
92              
93             Dan Book, C<dbook@cpan.org>
94              
95             =head1 COPYRIGHT AND LICENSE
96              
97             Copyright 2015, Dan Book.
98              
99             This library is free software; you may redistribute it and/or modify it under
100             the terms of the Artistic License version 2.0.
101              
102             =head1 SEE ALSO
103              
104             L<Perl::Critic>