File Coverage

blib/lib/Perl/Critic/Policy/Modules/RequireExplicitPackage.pm
Criterion Covered Total %
statement 46 47 97.8
branch 16 20 80.0
condition 5 6 83.3
subroutine 14 14 100.0
pod 6 7 85.7
total 87 94 92.5


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::Modules::RequireExplicitPackage;
2              
3 40     40   24879 use 5.010001;
  40         140  
4 40     40   160 use strict;
  40         91  
  40         700  
5 40     40   160 use warnings;
  40         58  
  40         1584  
6 40     40   218 use Readonly;
  40         94  
  40         2300  
7              
8 40     40   183 use Perl::Critic::Utils qw{ :booleans :severities :classification };
  40         66  
  40         2137  
9 40     40   12081 use parent 'Perl::Critic::Policy';
  40         79  
  40         202  
10              
11             our $VERSION = '1.156';
12              
13             #-----------------------------------------------------------------------------
14              
15             Readonly::Scalar my $EXPL => q{Violates encapsulation};
16             Readonly::Scalar my $DESC => q{Code not contained in explicit package};
17              
18             #-----------------------------------------------------------------------------
19              
20             sub supported_parameters {
21             return (
22             {
23 92     92 0 1160 name => 'exempt_scripts',
24             description => q{Don't require programs to contain a package statement.},
25             default_string => '1',
26             behavior => 'boolean',
27             },
28             {
29             name => 'allow_import_of',
30             description => q{Allow the specified modules to be imported outside a package},
31             behavior => 'string list',
32             },
33             );
34             }
35              
36 80     80 1 258 sub default_severity { return $SEVERITY_HIGH }
37 74     74 1 220 sub default_themes { return qw( core bugs ) }
38 32     32 1 67 sub applies_to { return 'PPI::Document' }
39              
40 36     36 1 73 sub default_maximum_violations_per_document { return 1; }
41              
42             #-----------------------------------------------------------------------------
43              
44             sub prepare_to_scan_document {
45 33     33 1 73 my ( $self, $document ) = @_;
46              
47 33   66     172 return ! $self->{_exempt_scripts} || $document->is_module();
48             }
49              
50             sub violates {
51 32     32 1 79 my ( $self, undef, $doc ) = @_;
52              
53             # Find the first 'package' statement
54 32         121 my $package_stmnt = $doc->find_first( 'PPI::Statement::Package' );
55 32 100       154 my $package_line = $package_stmnt ? $package_stmnt->location()->[0] : undef;
56              
57             # Find all statements that aren't 'package' statements
58 32         618 my $stmnts_ref = $doc->find( 'PPI::Statement' );
59 32 100       90 return if !$stmnts_ref;
60             my @non_packages = grep {
61 291         434 $self->_is_statement_of_interest( $_ )
62 30         55 } @{$stmnts_ref};
  30         59  
63 30 50       82 return if !@non_packages;
64              
65             # If the 'package' statement is not defined, or the other
66             # statements appear before the 'package', then it violates.
67              
68 30         51 my @viols;
69 30         68 for my $stmnt ( @non_packages ) {
70 262         525 my $stmnt_line = $stmnt->location()->[0];
71 262 100 100     3291 if ( (! defined $package_line) || ($stmnt_line < $package_line) ) {
72 5         20 push @viols, $self->violation( $DESC, $EXPL, $stmnt );
73             }
74             }
75              
76 30         111 return @viols;
77             }
78              
79             sub _is_statement_of_interest {
80 291     291   414 my ( $self, $elem ) = @_;
81              
82 291 50       604 $elem
83             or return $FALSE;
84              
85 291 100       765 $elem->isa( 'PPI::Statement::Package' )
86             and return $FALSE;
87              
88 262 100       545 if ( $elem->isa( 'PPI::Statement::Include' ) ) {
89 59 100       133 if ( my $module = $elem->module() ) {
    50          
90 57 50       1270 $self->{_allow_import_of}{$module}
91             and return $FALSE;
92             }
93             elsif ( $elem->version ) {
94 0         0 return $FALSE;
95             }
96             }
97              
98 262         487 return $TRUE;
99             }
100              
101             1;
102              
103             __END__
104              
105             #-----------------------------------------------------------------------------
106              
107             =pod
108              
109             =head1 NAME
110              
111             Perl::Critic::Policy::Modules::RequireExplicitPackage - Always make the C<package> explicit.
112              
113              
114             =head1 AFFILIATION
115              
116             This Policy is part of the core L<Perl::Critic|Perl::Critic>
117             distribution.
118              
119              
120             =head1 DESCRIPTION
121              
122             In general, the first statement of any Perl module or library should
123             be a C<package> statement. Otherwise, all the code that comes before
124             the C<package> statement is getting executed in the caller's package,
125             and you have no idea who that is. Good encapsulation and common
126             decency require your module to keep its innards to itself.
127              
128             There are some valid reasons for not having a C<package> statement at
129             all. But make sure you understand them before assuming that you
130             should do it too.
131              
132             One of those reasons is having a C<use VERSION> line as the first line
133             of your Perl file. It I<declares> which version of the Perl language
134             the following code is written. Because the effect is lexical, the previous
135             remarks about the caller's package do not apply.
136              
137             The maximum number of violations per document for this policy defaults
138             to 1.
139              
140              
141              
142             =head1 CONFIGURATION
143              
144             As for programs, most people understand that the default package is
145             C<main>, so this Policy doesn't apply to files that begin with a perl
146             shebang. If you want to require an explicit C<package> declaration in
147             all files, including programs, then add the following to your
148             F<.perlcriticrc> file
149              
150             [Modules::RequireExplicitPackage]
151             exempt_scripts = 0
152              
153             Some users may find it desirable to exempt the load of specific modules
154             from this policy. For example, Perl does not support Unicode module
155             names because of portability problems. Users who are not concerned about
156             this and intend to use C<UTF-8> module names will need to specify
157             C<use utf8;> before the package declaration. To do this, add the
158             following to your F<.perlcriticrc> file
159              
160             [Modules::RequireExplicitPackage]
161             allow_import_of = utf8
162              
163             The C<allow_import_of> configuration option takes multiple module names,
164             separated by spaces.
165              
166              
167             =head1 IMPORTANT CHANGES
168              
169             This policy was formerly called C<ProhibitUnpackagedCode> which
170             sounded a bit odd. If you get lots of "Cannot load policy module"
171             errors, then you probably need to change C<ProhibitUnpackagedCode> to
172             C<RequireExplicitPackage> in your F<.perlcriticrc> file.
173              
174              
175             =head1 AUTHOR
176              
177             Jeffrey Ryan Thalhammer <jeff@imaginative-software.com>
178              
179              
180             =head1 COPYRIGHT
181              
182             Copyright (c) 2005-2011 Imaginative Software Systems. All rights reserved.
183              
184             This program is free software; you can redistribute it and/or modify
185             it under the same terms as Perl itself. The full text of this license
186             can be found in the LICENSE file included with this module.
187              
188             =cut
189              
190             # Local Variables:
191             # mode: cperl
192             # cperl-indent-level: 4
193             # fill-column: 78
194             # indent-tabs-mode: nil
195             # c-indentation-style: bsd
196             # End:
197             # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :