File Coverage

blib/lib/Perl/Critic/Policy/Community/Prototypes.pm
Criterion Covered Total %
statement 40 41 97.5
branch 14 16 87.5
condition 17 22 77.2
subroutine 11 12 91.6
pod 4 5 80.0
total 86 96 89.5


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