The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Module::Util::Masked - mangle Module::Util to recognise module masking

SYNOPSIS

 perl -MModule::Util::Masked \
      -MTest::Without::Module=Some::Thing \
      myprog.pl ...

 perl -MModule::Util::Masked \
      -MModule::Mask::Deps \
      myprog.pl ...

 # or within a script
 use Module::Util::Masked;
 use Module::Mask;
 my $mask = Module::Mask->new ('Some::Thing');

DESCRIPTION

This module mangles Module::Util functions

    find_installed()
    all_installed()
    find_in_namespace()

to have them not return modules which are "masked" by any of

    Module::Mask
    Module::Mask::Deps
    Test::Without::Module
    Devel::Unplug

This is meant for testing, just as these masking modules are meant for testing, to pretend some modules are not available. Making the "find" functions in Module::Util reflect the masking helps code which checks module availability by a find rather than just eval{require...} or similar.

Load Order

Module::Util::Masked should be loaded before anything which might import the Module::Util functions, so such an import gets the mangled functions not the originals.

Usually this means loading Module::Util::Masked first, or early enough, but there's no attempt to detect or enforce that. A -M on the command line is good

    perl -MModule::Util::Masked myprog.pl ...

Or for the ExtUtils::MakeMaker testing harness the same in the usual HARNESS_PERL_SWITCHES environment variable,

    HARNESS_PERL_SWITCHES="-MModule::Util::Masked" make test

Otherwise somewhere near the start of a script

    use Module::Util::Masked;

Nothing actually changes in the Module::Util behaviour until one of the above mask modules such as Test::Without::Module is loaded and is asked to mask some modules. Then the mangled Module::Util will report such modules not found.

The mangling cannot be undone, but usually there's no need to. If some modules should be made visible again then ask the masking in Test::Without::Module etc to unmask them.

Implementation

Module::Mask is recognised by the object it adds to @INC.

Module::Mask::Deps is a subclass of Module::Mask and is recognised the same way.

Test::Without::Module is recognised by the fake_module() coderef it adds to @INC (which is not documented as such, so is dependent on the Test::Without::Module implementation).

The masking object or coderef in @INC is applied at the point it appears in the @INC list. This means any directory in @INC before the mask is unaffected, the same way it's unaffected for a require etc. The masking modules normally put themselves at the start of @INC and are therefore usually meant to act on everything.

Devel::Unplug is checked by its unplugged() list, when that function exists. It applies to any require so not to a particular place in @INC. Should an unplug be enforced when find_installed() etc is given a path, or only the default @INC? If a path is @INC plus or minus a few directories and then unplugging would be desirable, but if it's something unrelated then maybe not.

SEE ALSO

Module::Util, Module::Mask, Module::Mask::Deps, Test::Without::Module, Devel::Unplug

HOME PAGE

http://user42.tuxfamily.org/test-variousbits/index.html

COPYRIGHT

Copyright 2010, 2011, 2012, 2015, 2017 Kevin Ryde

Test-VariousBits is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version.

Test-VariousBits is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with Test-VariousBits. If not, see http://www.gnu.org/licenses/.