File Coverage

blib/lib/Devel/Unplug.pm
Criterion Covered Total %
statement 36 36 100.0
branch 12 12 100.0
condition 5 6 83.3
subroutine 11 11 100.0
pod 3 3 100.0
total 67 68 98.5


line stmt bran cond sub pod time code
1             package Devel::Unplug;
2              
3 5     5   195651 use warnings;
  5         13  
  5         160  
4 5     5   25 use strict;
  5         10  
  5         191  
5              
6             =head1 NAME
7              
8             Devel::Unplug - Simulate the non-availability of modules
9              
10             =head1 VERSION
11              
12             This document describes Devel::Unplug version 0.03
13              
14             =cut
15              
16 5     5   26 use vars qw($VERSION @ISA);
  5         20  
  5         2443  
17              
18             $VERSION = '0.03';
19              
20             =head1 SYNOPSIS
21              
22             $ perl -d:Unplug=Some::Module,Some::Other::Module myprog.pl
23             Can't locate Some/Module.pm in @INC (unplugged by Devel::Unplug) at myprog.pl line 5.
24             BEGIN failed--compilation aborted at myprog.pl line 5.
25            
26             =head1 DESCRIPTION
27              
28             Sometimes - particularly during testing - it's useful to be able to find
29             out how your code behaves when a module it is expecting is unavailable.
30             This module allows you to simulate the non-availability of a module.
31              
32             It uses L to replace C (and hence
33             C) and intercept attempts to load modules.
34              
35             =cut
36              
37             sub _get_module {
38 294     294   404 my $file = shift;
39 294         584 $file =~ s{/}{::}g;
40 294         1320 $file =~ s/[.]pm$//;
41 294         599 return $file;
42             }
43              
44             my %unplugged;
45              
46             sub _is_unplugged {
47 294     294   340 my $module = shift;
48              
49 294         519 for my $unp ( unplugged() ) {
50 47 100       267 return 1
    100          
51             if ( 'Regexp' eq ref $unp )
52             ? $module =~ $unp
53             : $module eq $unp;
54             }
55              
56 290         1131 return;
57             }
58              
59             =head1 INTERFACE
60              
61             None of these functions are exportable. Call them using their fully qualified names.
62              
63             =head2 C<< unplug >>
64              
65             Unplug one or more modules.
66              
67             Devel::Unplug::unplug( 'Some::Module', 'Some::Other::Module' );
68              
69             Regular expressions may be used:
70              
71             Devel::Unplug::unplug( qr{^Some:: (?: Other:: )? Module$}x );
72              
73             =cut
74              
75             sub unplug {
76 9     9 1 57 for my $unp ( @_ ) {
77 7 100 66     79 exists $unplugged{$unp} and $unplugged{$unp}->[1]++
78             or $unplugged{$unp} = [ $unp, 1 ];
79             }
80 9         101 return;
81             }
82              
83             =head2 C<< insert >>
84              
85             Make an unplugged module available again.
86              
87             Devel::Unplug::insert( 'Some::Module' );
88              
89             You must call C for a given module as many times as C
90             was called to make it available again.
91              
92             =cut
93              
94             sub insert {
95 8     8 1 3576 for my $mod ( @_ ) {
96 8 100 100     91 delete $unplugged{$mod}
97             if exists $unplugged{$mod} && 0 == --$unplugged{$mod}->[1];
98             }
99 8         86 return;
100             }
101              
102             BEGIN {
103 5     5   4808 use Devel::TraceLoad::Hook qw( register_require_hook );
  5         4479  
  5         24  
104             register_require_hook(
105             sub {
106 588         199203 my ( $when, $depth, $arg, $p, $f, $l, $rc, $err ) = @_;
107              
108 588 100       1739 return unless $when eq 'before';
109 294         514 my $module = _get_module( $arg );
110 294 100       535 return unless _is_unplugged( $module );
111              
112             # Ain't gonna let you load it
113 4         45 die "Can't locate $arg in \@INC (unplugged by " . __PACKAGE__ . ")";
114             }
115 5     5   902 );
116             }
117              
118             =head2 C<< unplugged >>
119              
120             Get the list of unplugged modules. The returned array may potentially
121             contain a mixture of regular expressions and plain strings.
122              
123             =cut
124              
125             sub unplugged {
126 302     302 1 2368 map { $_->[0] } values %unplugged;
  57         168  
127             }
128              
129             sub import {
130 4     4   29 my $class = shift;
131 4         13 unplug( @_ );
132             }
133              
134             1;
135             __END__