package FilterLoad; use warnings; use strict; use List::Util qw/ pairs pairkeys /; use PPI; use Module::Load::Conditional qw/ check_install /; use Module::Runtime qw/ use_module module_notional_filename /; =head1 DESCRIPTION Loads modules after passing them through the L filter(s) given in the C statement. For example: use FilterLoad 'AnyEvent::DNS' => 'Deconstifier', SomeModule => 'Deconstifier'; =cut sub import { my ($class, @defs) = @_; my (%mods, %filts); for ( pairs @defs ) { my ($mod, $filt) = @$_; $filts{$filt}++; my $modfn = module_notional_filename($mod); $mods{$modfn}{name} = $mod; push @{ $mods{$modfn}{filts} }, $filt; } use_module($_) for keys %filts; our $_in_inc_hook; unshift @INC, sub { my ($self, $modfn) = @_; return if $_in_inc_hook; return unless exists $mods{$modfn}; local $_in_inc_hook = 1; # check_install calls @INC hooks! my $info = check_install(module=>$mods{$modfn}{name}) or die "could not find $modfn"; my $doc = PPI::Document->new($info->{file}); $_->new->apply($doc) for @{ $mods{$modfn}{filts} }; return \$doc->serialize; }; use_module($_) for pairkeys @defs; } 1;