Perl::...clusion(3pm)
π Perl::...clusion(3pm) π
okay bestie, listen β this is a page from the User Contributed Perl Documentation and it's all about one very specific lil Perl::Critic policy. it's giving "your module lied about its friends" energy and honestly? iconic. let's get into it. π¦
β¨ NAME β¨
Perl::Critic::Policy::Modules::RequireExplicitInclusion
yes that's the whole name. it's long. she's a mouthful. we love her anyway. π
πΈ AFFILIATION πΈ
this policy is part of Perl::Critic::StricterSubs. that's her home. that's her family. π«Ά
π DESCRIPTION π
so here's the tea β: this policy checks that if you reference something inside another package, you've actually used or required a module with that package's name.
like, if you never import a package, it's honestly unlikely the stuff inside it even exists for you. and here's the sneaky part β because Perl is so flexible and does whatever it wants, use strict; can not complain about references to things outside the current package. so it just... won't detect this situation. no cap. it's a blind spot and this policy is the one holding the flashlight. π¦
π Explanation π
okay so picture this: there's a third-party Foo module with a bar() subroutine. and you go and make your own module:
package My::Module;
...
$x = Foo::bar($y);
...
and you're like "no worries, I fully qualified the name, so I don't have to care whether Foo exports bar() or not." or... do you? π
then you write a program called plugh that uses your module, and it also needs Foo directly:
#!/usr/bin/perl
...
use Foo;
use My::Module qw{ &frob };
...
and this works fine! everything's chill. slay. β¨
then later, you use your module inside a xyzzy program:
#!/usr/bin/perl
...
use My::Module qw{ &frob };
...
and suddenly you get compilation problems in the previously totally robust My::Module. π what is going ON?
here's what's going on: plugh loaded the Foo module before My::Module, which means when My::Module refers to Foo::bar(), that subroutine actually exists β even though My::Module never actually did a use Foo;. and then xyzzy tries to use My::Module without doing a use Foo;, and My::Module fails because Foo::bar() doesn't exist. it was living on borrowed vibes the whole time. π
π Enforcement π
assuming 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 count as valid. loading a file does not count. sorry babe. π
use Foo;
require Bar;
require 'Baz.pm';
$Foo:x = 57; #ok
$Bar:x = 57; #ok
$Baz:x = 57; #not ok
qualifying a name with the name of the current package is valid, and that's just correct:
package Xyzzy;
my $ducks;
sub increment_duck_count {
$Xyzzy::ducks++; #ok
}
and a use or require statement only gets taken into account when it's in the scope of a file or a BEGIN, CHECK, or INIT block. so like:
use File::Scope;
BEGIN {
require Begin::Block;
}
CHECK {
require Check::Block;
}
INIT {
require Init::Block;
}
END {
require End::Block;
}
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
{
require Lexical::Block;
push @Lexical::Block::numbers, 52, 93, 25; #not ok
}
noticed that END block? yeah. she doesn't count. and a lexical block? also no. π«
π CONFIGURATION π
you can configure a list of modules that this policy should just ignore. 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 this section to your perlcriticrc file:
[Modules::RequireExplicitInclusion]
ignore_modules = Test::Builder
and the ignore_modules argument can take a space-delimited list of modules, or of regexes, or both. bestie said "why not" and honestly, respect:
[Modules::RequireExplicitInclusion]
ignore_modules = Test::Builder /MooseX::/
π CAVEATS π
- it is assumed that the code for a package exists in a module of the same name. just... assuming that. taking it on faith. π§
- 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
packagestatements. for example, a module containing
package Foo;
sub frob {
$Xyzzy::factor = rand 100;
}
package Bar;
sub frob {
$Plugh::factor = rand 1000;
}
will not result in any violations. and honestly? there really shouldn't be more than one package within a module anyway. periodt. π
- no checks are done of whether the name actually exists in the referenced package. e.g., if a call to a
Foo::process_widgets()subroutine is made, this Policy does not check that aprocess_widgets()subroutine actually exists in theFoopackage. she's checking the inclusion, not the existence. different job. πΈ
π©Ί DIAGNOSTICS π©Ί
Modules::RequireExplicitInclusion: Cannot cope with multiple packages in filethis 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.
and that's the whole page bestie!! π no notes. go use your modules explicitly. iykyk.
this was perl v5.42.0, dated 2025-07-25 π mwah, love u, bye!! π¦β¨
π¦ where this page comes from
- fedora 43: perl-Perl-Critic-StricterSubs 0.08-3.fc43 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms