1 ##############################################################################
2 # $URL: http://perlcritic.tigris.org/svn/perlcritic/trunk/Perl-Critic/lib/Perl/Critic/Policy/Modules/RequireExplicitPackage.pm $
3 # $Date: 2008-07-03 10:19:10 -0500 (Thu, 03 Jul 2008) $
6 ##############################################################################
8 package Perl::Critic::Policy::Modules::RequireExplicitPackage;
15 use Perl::Critic::Utils qw{ :severities :classification };
16 use base 'Perl::Critic::Policy';
18 our $VERSION = '1.088';
20 #-----------------------------------------------------------------------------
22 Readonly::Scalar my $EXPL => q{Violates encapsulation};
23 Readonly::Scalar my $DESC => q{Code not contained in explicit package};
25 #-----------------------------------------------------------------------------
27 sub supported_parameters {
30 name => 'exempt_scripts',
31 description => q{Don't require programs to contain a package statement.},
32 default_string => '1',
33 behavior => 'boolean',
38 sub default_severity { return $SEVERITY_HIGH }
39 sub default_themes { return qw( core bugs ) }
40 sub applies_to { return 'PPI::Document' }
42 sub default_maximum_violations_per_document { return 1; }
44 #-----------------------------------------------------------------------------
48 my ( $self, $elem, $doc ) = @_;
50 # You can configure this policy to exclude scripts
51 return if $self->{_exempt_scripts} && is_script($doc);
53 # Find the first 'package' statement
54 my $package_stmnt = $doc->find_first( 'PPI::Statement::Package' );
55 my $package_line = $package_stmnt ? $package_stmnt->location()->[0] : undef;
57 # Find all statements that aren't 'package' statements
58 my $stmnts_ref = $doc->find( 'PPI::Statement' );
59 return if !$stmnts_ref;
60 my @non_packages = grep { !$_->isa('PPI::Statement::Package') } @{$stmnts_ref};
61 return if !@non_packages;
63 # If the 'package' statement is not defined, or the other
64 # statements appear before the 'package', then it violates.
67 for my $stmnt ( @non_packages ) {
68 my $stmnt_line = $stmnt->location()->[0];
69 if ( (! defined $package_line) || ($stmnt_line < $package_line) ) {
70 push @viols, $self->violation( $DESC, $EXPL, $stmnt );
81 #-----------------------------------------------------------------------------
87 Perl::Critic::Policy::Modules::RequireExplicitPackage - Always make the C<package> explicit.
92 This Policy is part of the core L<Perl::Critic> distribution.
97 In general, the first statement of any Perl module or
98 library should be a C<package> statement. Otherwise, all the code
99 that comes before the C<package> statement is getting executed in the
100 caller's package, and you have no idea who that is. Good
101 encapsulation and common decency require your module to keep its
104 There are some valid reasons for not having a C<package> statement at
105 all. But make sure you understand them before assuming that you
108 The maximum number of violations per document for this policy defaults to 1.
114 As for programs, most people understand that the default package is C<main>, so
115 this Policy doesn't apply to files that begin with a perl shebang. If you want
116 to require an explicit C<package> declaration in all files, including programs,
117 then add the following to your F<.perlcriticrc> file
119 [Modules::RequireExplicitPackage]
123 =head1 IMPORTANT CHANGES
125 This policy was formerly called C<ProhibitUnpackagedCode> which sounded
126 a bit odd. If you get lots of "Cannot load policy module" errors,
127 then you probably need to change C<ProhibitUnpackagedCode> to
128 C<RequireExplicitPackage> in your F<.perlcriticrc> file.
133 Jeffrey Ryan Thalhammer <thaljef@cpan.org>
138 Copyright (c) 2005-2008 Jeffrey Ryan Thalhammer. All rights reserved.
140 This program is free software; you can redistribute it and/or modify
141 it under the same terms as Perl itself. The full text of this license
142 can be found in the LICENSE file included with this module.
148 # cperl-indent-level: 4
150 # indent-tabs-mode: nil
151 # c-indentation-style: bsd
153 # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :