sourCEntral - mobile manpages

pdf

Perl::Critic::Policy::Modules::RequireExplicitInclusion

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.

  package My::Module;
  ...
  $x = Foo::bar($y);
  ...

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.

  #!/usr/bin/perl
  ...
  use Foo;
  use My::Module qw{ &frob };
  ...

This works fine. At some later time, you use your module in a xyzzy program.

  #!/usr/bin/perl
  ...
  use My::Module qw{ &frob };
  ...

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.

  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.

  package Xyzzy;
  my $ducks;
  sub increment_duck_count {
      $Xyzzy::ducks++;                           #ok
  }

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 {
      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
  }

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

  package Foo;
  sub frob {
      $Xyzzy::factor = rand 100;
  }
  package Bar;
  sub frob {
      $Plugh::factor = rand 1000;
  }

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.

CONFIGURATION

None.

DIAGNOSTICS

"Modules::RequireExplicitInclusion: Cannot cope with mutiple 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 AT cpan DOT org>

COPYRIGHT

Copyright (c) 2007 Jeffrey Ryan Thalhammer. All rights reserved.

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.

pdf