File Coverage

blib/lib/Perl/Critic/Policy/Freenode/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::Freenode::Prototypes;
2              
3 1     1   528 use strict;
  1         1  
  1         24  
4 1     1   4 use warnings;
  1         2  
  1         23  
5              
6 1     1   4 use Perl::Critic::Utils qw(:severities :classification :ppi);
  1         2  
  1         39  
7 1     1   304 use parent 'Perl::Critic::Policy';
  1         2  
  1         4  
8              
9             our $VERSION = '0.032';
10              
11 1     1   65 use constant DESC => 'Using function prototypes';
  1         2  
  1         53  
12 1     1   6 use constant EXPL => 'Function prototypes (sub foo ($@) { ... }) will usually not do what you want. Omit the prototype, or use signatures instead.';
  1         1  
  1         330  
13              
14             sub supported_parameters {
15             (
16             {
17 9     9 0 83705 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 13 sub default_severity { $SEVERITY_MEDIUM }
25 0     0 1 0 sub default_themes { 'freenode' }
26 9     9 1 107216 sub applies_to { 'PPI::Document' }
27              
28             sub violates {
29 9     9 1 114 my ($self, $elem) = @_;
30              
31             # Check if signatures are enabled
32 9   100     41 my $includes = $elem->find('PPI::Statement::Include') || [];
33 9         387 foreach my $include (@$includes) {
34 5 50       27 next unless $include->type eq 'use';
35 5 100 66     142 return () if $include->pragma eq 'feature' and $include =~ m/\bsignatures\b/;
36 4 100 66     129 return () if $include->pragma eq 'experimental' and $include =~ m/\bsignatures\b/;
37 3 100 66     77 return () if $include->module eq 'Mojo::Base' and $include =~ m/-signatures\b/;
38 2 100 66     41 return () if $include->module eq 'Mojolicious::Lite' and $include =~ m/-signatures\b/;
39 1 50       21 return () if exists $self->{_signature_enablers}{$include->module};
40             }
41            
42 4   100     14 my $prototypes = $elem->find('PPI::Token::Prototype') || [];
43 4         140 my @violations;
44 4         10 foreach my $prototype (@$prototypes) {
45             # Empty prototypes and prototypes containing & can be useful
46 3 100 100     14 next if $prototype->prototype eq '' or $prototype->prototype =~ /&/;
47 1         35 push @violations, $self->violation(DESC, EXPL, $prototype);
48             }
49            
50 4         263 return @violations;
51             }
52              
53             1;
54              
55             =head1 NAME
56              
57             Perl::Critic::Policy::Freenode::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::Freenode>.
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             [Freenode::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>