NAME
Perl::Critic::Policy::Modules::RequireExplicitInclusion
AFFILIATION
This policy is part of Perl::Critic::StricterSubs.
DESCRIPTION
Checks that, if a reference is made to something inside of another package, that a module with the name of the package has been use
d or require
d.
Without importing a package, it is unlikely that references to things inside it even exist. Due to the flexible nature of Perl, use strict;
can not complain about references to things outside of the current package and thus won't detect this situation.
Explanation
As an example, assume there is a third-party Foo
module with a bar()
subroutine. You then create a module of your own.
You don't have to worry about whether Foo
exports bar()
or not because you're fully qualifying the name. Or do you? You then create a program plugh that uses your module that also needs to use Foo
directly.
This works fine. At some later time, you use your module in a xyzzy program.
You now get compilation problems in the previously robust My::Module
. What is going on is that plugh loaded the Foo
module prior to My::Module
, which means that, when My::Module
refers to Foo::bar()
, the subroutine actually exists, even though My::Module
didn't actually use Foo;
. When xyzzy attempted to use My::Module
without doing a use Foo;
, My::Module
fails because Foo::bar()
doesn't exist.
Enforcement
Assuming that there are no use
or require
statements within the current scope:
@foo
=
localtime
;
#ok
@Bar::foo
=
localtime
#not ok
@::foo =
localtime
;
#ok
@main::foo
=
localtime
;
#ok
baz(23,
'something'
,
$x
);
#ok
Bar::baz(23,
'something'
,
$x
);
#not ok
::baz(23,
'something'
,
$x
);
#ok
main::baz(23,
'something'
,
$x
);
#ok
Only modules that are symbolically referenced by a use
or require
are considered valid. Loading a file does not count.
Qualifying a name with the name of the current package is valid.
A use
or require
statement is taken into account only when it is in the scope of a file or a BEGIN
, CHECK
, or INIT
block.
use
File::Scope;
BEGIN {
}
CHECK {
}
INIT {
}
END {
}
push
@File::Scope::numbers
, 52, 93, 25;
#ok
push
@Begin::Block::numbers
, 52, 93, 25;
#ok
push
@Check::Block::numbers
, 52, 93, 25;
#ok
push
@Init::Block::numbers
, 52, 93, 25;
#ok
push
@End::Block::numbers
, 52, 93, 25;
#not ok
{
push
@Lexical::Block::numbers
, 52, 93, 25;
#not ok
}
CONFIGURATION
You can configure a list of modules that should be ignored by this policy. For example, it's common to use Test::Builder's variables in functions built on Test::More.
use
Test::More
sub
test_something {
local
$Test::Builder::Level
=
$Test::Builder::Level
+ 1;
return
is( ... );
}
Using Test::More also brings in Test::Builder, so you don't need to do a call to use
. Unfortunately that trips this policy.
So to ignore violations on Test::Builder, you can add to your perlcriticrc file this section:
[Modules::RequireExplicitInclusion]
ignore_modules = Test::Builder
The ignore_modules
argument can take a space-delimited list of modules, or of regexes, or both.
[Modules::RequireExplicitInclusion]
ignore_modules = Test::Builder /MooseX::/
CAVEATS
1.) It is assumed that the code for a package exists in a module of the same name.
2.) It is assumed that a module will contain no more than one package. This Policy will not complain about any problems in a module containing multiple package
statements. For example, a module containing
will not result in any violations. There really shouldn't be more than one package within a module anyway.
3.) No checks of whether the name actually exists in the referenced package are done. E.g., if a call to a Foo::process_widgets()
subroutine is made, this Policy does not check that a process_widgets()
subroutine actually exists in the Foo
package.
DIAGNOSTICS
Modules::RequireExplicitInclusion: Cannot cope with multiple packages in file
-
This warning happens when the file under analysis contains multiple packages, which is not currently supported. This Policy will simply ignore any file with multiple packages.
Perl::Critic advises putting multiple packages in one file, and has additional Policies to help enforce that.
SEE ALSO
Perl::Critic::Policy::Modules::ProhibitMultiplePackages
AUTHOR
Jeffrey Ryan Thalhammer <thaljef@cpan.org>
COPYRIGHT
Copyright 2007-2024 Jeffrey Ryan Thalhammer and Andy Lester
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. The full text of this license can be found in the LICENSE file included with this module.