File Coverage

blib/lib/Perl/Critic/Policy/Modules/RequireExplicitPackage.pm
Criterion Covered Total %
statement 46 46 100.0
branch 17 18 94.4
condition 6 6 100.0
subroutine 14 14 100.0
pod 6 7 85.7
total 89 91 97.8


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::Modules::RequireExplicitPackage;
2              
3 40     40   26736 use 5.010001;
  40         168  
4 40     40   240 use strict;
  40         83  
  40         821  
5 40     40   245 use warnings;
  40         120  
  40         1207  
6 40     40   217 use Readonly;
  40         108  
  40         2300  
7              
8 40     40   328 use Perl::Critic::Utils qw{ :booleans :severities :classification };
  40         116  
  40         2140  
9 40     40   15356 use parent 'Perl::Critic::Policy';
  40         117  
  40         252  
10              
11             our $VERSION = '1.148';
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 104     104 0 2285 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 90     90 1 426 sub default_severity { return $SEVERITY_HIGH }
37 74     74 1 368 sub default_themes { return qw( core bugs ) }
38 43     43 1 125 sub applies_to { return 'PPI::Document' }
39              
40 47     47 1 161 sub default_maximum_violations_per_document { return 1; }
41              
42             #-----------------------------------------------------------------------------
43              
44             sub prepare_to_scan_document {
45 45     45 1 143 my ( $self, $document ) = @_;
46              
47 45   100     234 return ! $self->{_exempt_scripts} || $document->is_module();
48             }
49              
50             sub violates {
51 43     43 1 128 my ( $self, $elem, $doc ) = @_;
52              
53             # Find the first 'package' statement
54 43         187 my $package_stmnt = $doc->find_first( 'PPI::Statement::Package' );
55 43 100       275 my $package_line = $package_stmnt ? $package_stmnt->location()->[0] : undef;
56              
57             # Find all statements that aren't 'package' statements
58 43         949 my $stmnts_ref = $doc->find( 'PPI::Statement' );
59 43 100       314 return if !$stmnts_ref;
60             my @non_packages = grep {
61 318         629 $self->_is_statement_of_interest( $_ )
62 40         104 } @{$stmnts_ref};
  40         119  
63 40 100       177 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 38         86 my @viols = ();
69 38         121 for my $stmnt ( @non_packages ) {
70 280         754 my $stmnt_line = $stmnt->location()->[0];
71 280 100 100     5078 if ( (! defined $package_line) || ($stmnt_line < $package_line) ) {
72 16         149 push @viols, $self->violation( $DESC, $EXPL, $stmnt );
73             }
74             }
75              
76 38         209 return @viols;
77             }
78              
79             sub _is_statement_of_interest {
80 318     318   641 my ( $self, $elem ) = @_;
81              
82 318 50       808 $elem
83             or return $FALSE;
84              
85 318 100       1067 $elem->isa( 'PPI::Statement::Package' )
86             and return $FALSE;
87              
88 281 100       868 if ( $elem->isa( 'PPI::Statement::Include' ) ) {
89 64 100       247 if ( my $module = $elem->module() ) {
90 62 100       1821 $self->{_allow_import_of}{$module}
91             and return $FALSE;
92             }
93             }
94              
95 280         751 return $TRUE;
96             }
97              
98             1;
99              
100             __END__
101              
102             #-----------------------------------------------------------------------------
103              
104             =pod
105              
106             =head1 NAME
107              
108             Perl::Critic::Policy::Modules::RequireExplicitPackage - Always make the C<package> explicit.
109              
110              
111             =head1 AFFILIATION
112              
113             This Policy is part of the core L<Perl::Critic|Perl::Critic>
114             distribution.
115              
116              
117             =head1 DESCRIPTION
118              
119             In general, the first statement of any Perl module or library should
120             be a C<package> statement. Otherwise, all the code that comes before
121             the C<package> statement is getting executed in the caller's package,
122             and you have no idea who that is. Good encapsulation and common
123             decency require your module to keep its innards to itself.
124              
125             There are some valid reasons for not having a C<package> statement at
126             all. But make sure you understand them before assuming that you
127             should do it too.
128              
129             The maximum number of violations per document for this policy defaults
130             to 1.
131              
132              
133              
134             =head1 CONFIGURATION
135              
136             As for programs, most people understand that the default package is
137             C<main>, so this Policy doesn't apply to files that begin with a perl
138             shebang. If you want to require an explicit C<package> declaration in
139             all files, including programs, then add the following to your
140             F<.perlcriticrc> file
141              
142             [Modules::RequireExplicitPackage]
143             exempt_scripts = 0
144              
145             Some users may find it desirable to exempt the load of specific modules
146             from this policy. For example, Perl does not support Unicode module
147             names because of portability problems. Users who are not concerned about
148             this and intend to use C<UTF-8> module names will need to specify
149             C<use utf8;> before the package declaration. To do this, add the
150             following to your F<.perlcriticrc> file
151              
152             [Modules::RequireExplicitPackage]
153             allow_import_of = utf8
154              
155             The C<allow_import_of> configuration option takes multiple module names,
156             separated by spaces.
157              
158              
159             =head1 IMPORTANT CHANGES
160              
161             This policy was formerly called C<ProhibitUnpackagedCode> which
162             sounded a bit odd. If you get lots of "Cannot load policy module"
163             errors, then you probably need to change C<ProhibitUnpackagedCode> to
164             C<RequireExplicitPackage> in your F<.perlcriticrc> file.
165              
166              
167             =head1 AUTHOR
168              
169             Jeffrey Ryan Thalhammer <jeff@imaginative-software.com>
170              
171              
172             =head1 COPYRIGHT
173              
174             Copyright (c) 2005-2011 Imaginative Software Systems. All rights reserved.
175              
176             This program is free software; you can redistribute it and/or modify
177             it under the same terms as Perl itself. The full text of this license
178             can be found in the LICENSE file included with this module.
179              
180             =cut
181              
182             # Local Variables:
183             # mode: cperl
184             # cperl-indent-level: 4
185             # fill-column: 78
186             # indent-tabs-mode: nil
187             # c-indentation-style: bsd
188             # End:
189             # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :