File Coverage

blib/lib/Acme/Globule.pm
Criterion Covered Total %
statement 32 32 100.0
branch 6 6 100.0
condition n/a
subroutine 9 9 100.0
pod n/a
total 47 47 100.0


line stmt bran cond sub pod time code
1             package Acme::Globule;
2             BEGIN {
3 6     6   153727 $Acme::Globule::DIST = 'Acme-Globule';
4             }
5             BEGIN {
6 6     6   109 $Acme::Globule::VERSION = '0.004';
7             }
8             # ABSTRACT: Extensible package-local way to override glob()
9 6     6   50 use warnings;
  6         12  
  6         180  
10 6     6   32 use strict;
  6         25  
  6         254  
11              
12             # a quick dance to get at the glob()/<> implementation that we replace with
13             # a wrapper
14 6     6   33 use File::Glob qw( csh_glob );
  6         11  
  6         784  
15             my $csh_glob = \&csh_glob;
16              
17 6     6   5516 use Module::Load;
  6         6625  
  6         52  
18              
19             # This is a hash mapping packages that use us to the Globule plugins they
20             # requested.
21             my %clients;
22              
23             # This is a hash of plugins that have been pulled in so far, and maps to the
24             # name of the package that actually implements the plugin.
25             my %plugins;
26              
27             sub import {
28 7     7   56 my($self, @plugins) = @_;
29 7         21 my($importer) = caller;
30              
31 7         16 foreach my $plugin (@plugins) {
32 6 100       32 unless (defined $plugins{$plugin}) {
33 5         46 my $pkgname = __PACKAGE__."::$plugin";
34 5         18 load $pkgname;
35 4         73 $plugins{$plugin} = $pkgname;
36             }
37             }
38              
39 6         9795 $clients{$importer} = \@plugins;
40             }
41              
42             sub _new_csh_glob {
43 29     29   35236 my($pattern) = @_;
44 29         80 my($caller) = caller; # contains package of caller, or (eval) etc, but
45             # will match an entry in %clients for any package
46             # that imported us
47 29 100       112 if (my $client = $clients{$caller}) {
48             # The caller imported us, so we work through the plugins they requested
49 28         58 foreach my $plugin (@$client) {
50             # Try the pattern against each plugin in turn, until one returns a
51             # true value. This is assumed to be an arrayref that contains the
52             # result of the glob
53 27         126 my $result = $plugins{$plugin}->globule($pattern);
54 27 100       788 return @$result if $result;
55             }
56             }
57             # Since no plugins matched (or the caller didn't import us), we fall
58             # through to the original glob function
59 3         175 goto &$csh_glob;
60             }
61              
62 6     6   1529 no warnings; # we don't want "subroutine redefined" diagnostics
  6         13  
  6         389  
63             *File::Glob::csh_glob = \&_new_csh_glob;
64             *CORE::GLOBAL::glob = \&File::Glob::csh_glob;
65              
66             1;
67              
68              
69             1;
70              
71             __END__