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

NAME

Module::Mask - Pretend certain modules are not installed

SYNOPSIS

    use Module::Mask;

    {
        my $mask = new Module::Mask ('My::Module');
        eval { require My::Module };
        if ($@) {
            # ... should be called
        }
        else {
            warn "require succeeded unexpectedly"
        }
    }
    
    # The mask is out of scope, this should now work.
    eval { require My::Module };

    # There's also an inverted version:
    {
        my $mask = new Module::Mask::Inverted qw( Foo Bar );

        # Now only Foo and Bar can be loaded by require:
        eval {require Baz};
    }

DESCRIPTION

Sometimes you need to test what happens when a given module is not installed. This module provides a way of temporarily hiding installed modules from perl's require mechanism. The Module::Mask object adds itself to @INC and blocks require calls to restricted modules.

Module::Mask will not affect modules already loaded at time of instantiation.

METHODS

import

    use Module::Mask @modules;

    $class->import(@modules);

Globally masks modules. This can be used to block optional modules for testing purposes.

    perl -MModule::Mask=MyOptionalModule my_test.pl

new

    $obj = $class->new(@modules);

Returns a new instance of this class. Any arguments are passed to mask_modules.

mask_modules

    $obj = $obj->mask_modules(@modules)

Add the given modules to the mask. Arguments can be paths or module names, module names will be stored internally as relative paths. So there's no difference between the following statements:

    $mask->mask_modules('My::Module');
    $mask->mask_modules('My/Module.pm');

clear_mask

    $obj = $obj->clear_mask()

Stops the object from masking modules by removing it from @INC. This is automatically called when object goes out of scope.

set_mask

    $obj = $obj->set_mask()

Makes the object start masking modules by adding it to @INC. This is called by new().

This also has the effect of moving the object to the front of @INC again, which could prove useful if @INC has been manipulated since the object was first instantiated.

Calling this method on an object already in @INC won't cause multiple copies to appear.

is_masked

    $bool = $obj->is_masked($module)

Returns true if the mask object is currently masking the given module, false otherwise.

Module::Mask::Inverted objects have the opposite behaviour.

list_masked

    @modules = $obj->list_masked()

Returns a list of modules that are being masked. These are in the form of relative file paths, as found in %INC.

INC

Implements the hook in @INC. See perldoc -f require

message

    $message = $obj->message($filename)

Returns the error message to be used when the filename is not found. This is normally "$filename masked by $class", but can be overridden in subclasses if necessary. Carp's shortmess is used to make this message appear to come from the caller, i.e. the require or use statement attempting to load the file.

One possible application of this would be to make the error message look more like perl's native "Could not find $filename in \@INC ...".

BUGS

Because loaded modules cannot be masked, the following module are effectively never able to be masked as they are used my Module::Mask.

  • Module::Util

  • Scalar::Util

  • Carp

Plus some other core modules and pragmata used by these.

Run

    perl -MModule::Mask -le 'print for keys %INC'

To see a definitive list.

SEE ALSO

perldoc -f require

Module::Util

AUTHOR

Matt Lawrence <mattlaw@cpan.org>