Kevin Ryde
and 1 contributors


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


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

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

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


This module mangles Module::Util functions


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


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 ...

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.


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.


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



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