Module-Pluggable-5.1000755000765000024 012262457022 14117 5ustar00simonstaff000000000000Module-Pluggable-5.1/Build.PL000444000765000024 356412262457022 15560 0ustar00simonstaff000000000000use strict; use Module::Build; use FindBin; use File::Spec::Functions qw(catfile); # VOS and VMS can't handle dodgy plugin names # and VOS can't even unpack them so we create them on the # fly and only run the tests if they're present my %dodgy_files = ( catfile(qw(OddTest Plugin -Dodgy.pm)) => 'OddTest::Plugin::-Dodgy', catfile(qw(EditorJunk Plugin #Bar.pm#)) => 'EditorJunk::Bar', catfile(qw(EditorJunk Plugin .#Bar.pm)) => 'EditorJunk::Bar', ); my $core = grep { $_ eq 'PERL_CORE=1' } @ARGV; my @path = $core ? (File::Spec->updir, File::Spec->updir, File::Spec->updir, "t", "Module_Pluggable") : ($FindBin::Bin,"t"); my @files; unless (grep { lc($^O) eq $_ } qw(vms vos)) { foreach my $test (keys %dodgy_files) { my ($file) = (catfile(@path, "lib", $test)=~/^(.*)$/); if (open(FH, ">$file")) { my $name = $dodgy_files{$test}; print FH "package $name;\nsub new {}\n1;"; close(FH); push @files, $file; } } } my $build = Module::Build ->new( module_name => "Module::Pluggable", license => 'perl', requires => { 'if' => '0', 'File::Basename' => '0', 'File::Spec' => '3.00', }, configure_requires => { 'Module::Build' => '0.38', }, build_requires => { 'Test::More' => '0.62', }, create_makefile_pl => 'small', installdirs => ((($] >= 5.008009) && ($] < 5.011)) ? 'core' : 'site'), meta_merge => { resources => { repository => 'https://github.com/simonwistow/Module-Pluggable', } }, ); $build->add_to_cleanup(@files); $build->build_elements([grep { $_ ne 'pod' } @{$build->build_elements}]) if $core; $build->create_build_script; Module-Pluggable-5.1/Changes000555000765000024 2017212262457022 15574 0ustar00simonstaff0000000000002014-01-05 - 5.1 Add in missing files left out of the MANIFEST due to stupidity (thanks to Petr Pisar) 2013-12-20 - 5.0 Gain support for @INC hooks and hence for App::FatPacker (thanks to Diab Jerius) 2013-10-22 - 4.9 Fix the fact that we can't handle single letter package names (thanks sbaynes) 2013-05-27 - 4.8 Fix some typos (David Steinbrunner) Fix error in testing when Text::BibTex is installed (thanks to Andreas Koenig) 2013-02-25 - 4.7 Fix more hash ordering bugs in tests by forcing sort of returned plugins (Yves Orton) 2013-01-23 - 4.6 Add warning about future removal from core 2012-11-05 - 4.5 Fix docs Fix problem with PAUSE upload 2012-11-05 - 4.4 Fix hash ordering bug in tests (Yves Orton) Fix install dir (Tatsuhiko Miyagawa) 2012-08-15 - 4.3 Fix calling the correct method when instantiating (Doh!) Hopefully stop smoker failures 2012-08-14 - 4.2 Fix a problem with installation directory (Jerry D. Hedden) 2012-07-20 - 4.1 Allow triggers on events which gives a powerful way to modify behaviour (Tim Brody, Dan Dascalescu, Paul Evans, Jens Rehsack) Put documentation in about behaviour under blib and test, allow searching outside blib under test (suggestion from Stephen Baynes) Made following symlinks the default behaviour, added ability to turn that off (Aran Deltac) Fix installation path (Matthias Dietrich, Todd Rinaldo) Allow min_depth and max_depth (as per suggestion from Jens Rehsack) Set our @INC up to include and prefer our search_dirs if necessary (as per suggestion from Ian Goodacre) Switch to Module::Build 2012-01-03 - 4.0 Don't use defined on an array (it's deprecated) 2009-03-02 - 3.9 Allow inner packages when in a one file situation (suggestion from Christopher Brown) Fix bug with requiring skipped packages (from Jos Boumans) 2008-03-16 - 3.8 Set INSTALLDIRS correctly in Makefile.PL A couple of other fixups to play nicely in Core 2008-03-12 - 3.7 Ignore editor cruft by default (Dave Rolsky and Matt Trout) Doc patches (Matt Trout) Prevent prototype mismatch warnings under Error.pm (Christopher H. Laco) Don't pick up the ::SUPER pseudo stash in 5.8 (Alex Vandiver) Make things work under VOS (Nicholas Clark and Paul Green) Fix warning under Devel::Cover (Brian Cassidy) Make tests run under Taint again Get rid of Build.PL 2007-04-07 - 3.6 Include blead perl patch from Craig Berry that gives better Module::Pluggable::Object::search_paths portability as prompted by VMS test failures. 2007-01-29 - 3.5 Patch from Audrey Tang to prevent clobbering of $@ 2006-11-27 - 3.4 Make sure we don't fail taint checking when other Module::Pluggable::* modules are installed. 2006-11-24 - 3.3 Few more patches from Jos Boumans to get ready for CORE 2006-11-15 - 3.2 Remove Class::Inspector dependency and inline code Prepare for assimilation into CORE 2006-07-11 - 3.1 Force Test::More version to be latest which stops it trampling on $_ Use Class::Inspector tests to check to see Package is loaded thus preventing incompatability problems introduced by last patch. 2006-06-07 - 3.01 Fix from Brian Cassidy in Devel::InnerPackage 2006-06-06 - 3.0 Big refactor to split stuff up into more manageable pieces 2006-04-05 - 2.98 Allow the ability to provide the file matching regex 2006-02-06 - 2.97 Patch from Ricardo Signes to fix bug where File::Find is not topic-safe in 5.6.1 2005-09-01 - 2.96 Patch from Alex Vandiver to sort an edge case where the package stash to contain "::" 2005-07-30 - 2.95 Patch from Alex Vandiver to sort ::ISA::CACHE issues. More patches from Christopher H. Laco to sort out only and except and to fix calling search_path( add => ... ) before plugins() 2005-07-09 - 2.9 More Tainting fixes Patches from Christopher H. Laco and Joe McMahon to do more taint fixing Suggestion from Christopher H. Laco to do a can check before instatiating 2005-03-18 - 2.8 Minor fixes Patch from Marcus Thiesen to fix so ISA cache magic Patch from Anthony D. Urso to get M::P to work under taint 2005-02-14 - 2.7 Allow redefinition of search_path A patch from Barbie to allow you to do $self->search_path( add => 'Some::Path' ); $self->search_path( new => 'Some::New::Path' ); 2005-02-02 - 2.6 Problems under tests Richard Clamp diagnosed a problem as being due to the fact that we exclude anything not from blib if there was blib.pm is %INC. Of course if the module being tested used another module that used Module::Pluggable then the second module would fail. Fixed it by checking to see if the caller had (^|/)blib/ in their filename. 2004-12-20 - 2.5 'Inspiration' from Module::Pluggable::Fast Noticed Sebastian Riedel's curious Module::Pluggable::Fast which appears to break API backwards compatability in order to inline an explicit call to 'new'. It has no tests. A quick benchmark showed that it was about 10% faster because of cruft that had accumulated over time. So a few quick changes and now Module::Pluggable is only 3% slower. Which is nice. Also added a patch from Barbie to fix things under Windows. 2004-12-15 - 2.4 Bug fix There seemed to be some irregularities in how 5.8.1 worked with the list_packages method. Fixed thanks to Schwern, Michael Cummings and Jos Boumans. Added some more documentation. Added ability to specify except and only as regexes. 2004-10-27 - 2.3 Niceties Allow you to explicitly stop looking for inner packages. Made it nicer to have single element search_dirs and search_paths. 2004-10-08 - 2.2 Dieting Thanks to suggestion and patches from Adam Kennedy Module::Pluggable has dumped some weight and got rid of the none Core dependecies of File::Find::Rule and UNIVERSAL::require 2004-08-25 - 2.1 Small buglette Require inner packages when appropriate. This helps towards making things work with PAR. Thanks to Brian Cassidy. Never released. 2004-08-19 - 2.0 Working inner packages As long as you have require or instantiate set then we'll also find inner packages. Why I didn't fix this way back in 1.3 I don't know. 2004-07-18 - 1.9 Add 'package' option This lets you install a method in another package's namespace. Thanks to Simon Cozens. 2004-07-08 - 1.8 Fix those two options They worked before but now they're more robust. 2004-07-07 - 1.7 Add support for limiting plugins Added 'only' and ''except' options. 2004-06-03 - 1.6 Add a traditional Makefile.PL Even though I think Module::Build is much better. 2004-05-25 - 1.5 Build.PL stupidity Must add prereqs. Doh. 2004-05-25 - 1.4 Multiple instances Made it so you could use it twice in the same package. Removed the inner package stuff inorder to fix it properly. 2004-05-06 - 1.3 Ability to search in inner packages Simon Cozens donated some code to allow us to search inner packages. 2004-05-06 - 1.2 Fix minor buglet Apply a patch from Tom Insam to fix requiring without instantiating and make require failures more verbose. 2003-12-15 - 1.11 Update MANIFEST. So that make dist works properly. 2003-12-15 - 1.1 Make it work with multi level plugins Apparently Foo::Plugin::Bar::Quux doesn't work. Thanks to Darren Chamberlain for spotting this. 2003-12-15 - 1.00 Add some more features Added the ability to require without instantiating (for Tom Insam) Prevented the names from being explicitly sorted (again, for Tom Insam) Added in the ability to provide other search directorys. 2003-11-27 - 0.95 Some Test::More issues Explicitly number the tests which fixes some test more failures 2003-10-21 - 0.9 We can rebuild you, we have the technology Having used this in the wild some changes to make it better. 2003-10-20 - 0.8 Fix. Namespace issues. 2003-10-17 - 0.7 And take your Build.PL with you Pesky MANIFEST.SKIP 2003-10-15 - 0.6 Initial release Be free my pretty. EMANCIPIA! Module-Pluggable-5.1/INSTALL000555000765000024 22412262457022 15266 0ustar00simonstaff000000000000 Same as practically every other Perl module ... % perl Build.PL % ./Build % ./Build test % sudo ./Build install Module-Pluggable-5.1/Makefile.PL000444000765000024 42512262457022 16207 0ustar00simonstaff000000000000# Note: this file was auto-generated by Module::Build::Compat version 0.4007 use Module::Build::Compat 0.02; Module::Build::Compat->run_build_pl(args => \@ARGV); require Module::Build; Module::Build::Compat->write_makefile(build_class => 'Module::Build'); Module-Pluggable-5.1/MANIFEST000444000765000024 363312262457022 15412 0ustar00simonstaff000000000000Build.PL Changes INSTALL lib/Devel/InnerPackage.pm lib/Module/Pluggable.pm lib/Module/Pluggable/Object.pm Makefile.PL MANIFEST This list of files MANIFEST.SKIP META.json META.yml README t/01use.t t/02alsoworks.t t/02works.t t/02works_taint.t t/03diffname.t t/04acmedir.t t/04acmedir_single.t t/04acmepath.t t/04acmepath_single.t t/05postpath.t t/06multipath.t t/07instantiate.t t/08nothing.t t/09require.t t/10innerpack.t t/10innerpack_inner.t t/10innerpack_noinner.t t/10innerpack_onefile.t t/10innerpack_override.t t/10innerpack_super.t t/11usetwice.t t/12only.t t/12onlyarray.t t/12onlyregex.t t/12onlyrequire.t t/13except.t t/13exceptarray.t t/13exceptregex.t t/14package.t t/15topicsafe.t t/16different_extension.t t/17devel_inner_package.t t/18skipped_package.t t/19can_ok_clobber.t t/20dodgy_files.t t/21editor_junk.t t/22trigger.t t/23depth.t t/24local_inc_object.t t/24local_inc_package.t t/25single_letter_package.t t/26inc_hook.t t/27app_fatpacker.t t/acme/Acme/MyTest/Plugin/Foo.pm t/fp/app.pl t/fp/lib/App/TestMPFP/Plugin/A.pm t/lib/Acme/Foo-Bar.pm t/lib/Acme/MyTest/Plugin/Foo.pm t/lib/EditorJunk/Plugin/Bar.pm t/lib/EditorJunk/Plugin/Bar.pm.swo t/lib/EditorJunk/Plugin/Bar.pm.swp t/lib/EditorJunk/Plugin/Bar.pm~ t/lib/EditorJunk/Plugin/Foo.pm t/lib/ExtTest/Plugin/Bar.plugin t/lib/ExtTest/Plugin/Foo.plugin t/lib/ExtTest/Plugin/Quux/Foo.plugin t/lib/InnerTest/Plugin/Foo.pm t/lib/M/X.pm t/lib/MyOtherTest/Plugin/Bar.pm t/lib/MyOtherTest/Plugin/Foo.pm t/lib/MyOtherTest/Plugin/Quux.pm t/lib/MyOtherTest/Plugin/Quux/Foo.pm t/lib/MyTest/Extend/Plugin/Bar.pm t/lib/MyTest/Plugin/Bar.pm t/lib/MyTest/Plugin/Foo.pm t/lib/MyTest/Plugin/Quux/Foo.pm t/lib/No/Middle.pm t/lib/OddTest/Plugin/Foo.pm t/lib/TA/C/A/I.pm t/lib/Text/Abbrev.pm t/lib/TriggerTest/Plugin/After.pm t/lib/TriggerTest/Plugin/CallbackAllow.pm t/lib/TriggerTest/Plugin/CallbackDeny.pm t/lib/TriggerTest/Plugin/Deny.pm t/lib/TriggerTest/Plugin/Error.pm t/lib/Zot/.Zork.pm Module-Pluggable-5.1/MANIFEST.SKIP000444000765000024 31412262457022 16130 0ustar00simonstaff000000000000Build$ _build blib Makefile$ \.tar\.gz$ \.svn \.git \.bak$ ^Module-Pluggable t/lib/OddTest/Plugin/-Dodgy.pm t/lib/EditorJunk/Plugin/#Bar.pm# t/lib/EditorJunk/Plugin/.#Bar.pm ^MYMETA\.yml$ ^MYMETA\.json$ Module-Pluggable-5.1/META.json000444000765000024 264712262457022 15706 0ustar00simonstaff000000000000{ "abstract" : "automatically give your module the ability to have plugins", "author" : [ "Simon Wistow " ], "dynamic_config" : 1, "generated_by" : "Module::Build version 0.4007, CPAN::Meta::Converter version 2.120351", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "Module-Pluggable", "prereqs" : { "build" : { "requires" : { "Test::More" : "0.62" } }, "configure" : { "requires" : { "Module::Build" : "0.38" } }, "runtime" : { "requires" : { "File::Basename" : "0", "File::Spec" : "3.00", "if" : "0" } } }, "provides" : { "Devel::InnerPackage" : { "file" : "lib/Devel/InnerPackage.pm", "version" : "0.4" }, "Module::Pluggable" : { "file" : "lib/Module/Pluggable.pm", "version" : "5.1" }, "Module::Pluggable::Object" : { "file" : "lib/Module/Pluggable/Object.pm", "version" : "5.1" } }, "release_status" : "stable", "resources" : { "license" : [ "http://dev.perl.org/licenses/" ], "repository" : { "url" : "https://github.com/simonwistow/Module-Pluggable" } }, "version" : "5.1" } Module-Pluggable-5.1/META.yml000444000765000024 153412262457022 15530 0ustar00simonstaff000000000000--- abstract: 'automatically give your module the ability to have plugins' author: - 'Simon Wistow ' build_requires: Test::More: 0.62 configure_requires: Module::Build: 0.38 dynamic_config: 1 generated_by: 'Module::Build version 0.4007, CPAN::Meta::Converter version 2.120351' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: Module-Pluggable provides: Devel::InnerPackage: file: lib/Devel/InnerPackage.pm version: 0.4 Module::Pluggable: file: lib/Module/Pluggable.pm version: 5.1 Module::Pluggable::Object: file: lib/Module/Pluggable/Object.pm version: 5.1 requires: File::Basename: 0 File::Spec: 3.00 if: 0 resources: license: http://dev.perl.org/licenses/ repository: https://github.com/simonwistow/Module-Pluggable version: 5.1 Module-Pluggable-5.1/README000555000765000024 2410712262457022 15163 0ustar00simonstaff000000000000NAME Module::Pluggable - automatically give your module the ability to have plugins SYNOPSIS Simple use Module::Pluggable - package MyClass; use Module::Pluggable; and then later ... use MyClass; my $mc = MyClass->new(); # returns the names of all plugins installed under MyClass::Plugin::* my @plugins = $mc->plugins(); EXAMPLE Why would you want to do this? Say you have something that wants to pass an object to a number of different plugins in turn. For example you may want to extract meta-data from every email you get sent and do something with it. Plugins make sense here because then you can keep adding new meta data parsers and all the logic and docs for each one will be self contained and new handlers are easy to add without changing the core code. For that, you might do something like ... package Email::Examiner; use strict; use Email::Simple; use Module::Pluggable require => 1; sub handle_email { my $self = shift; my $email = shift; foreach my $plugin ($self->plugins) { $plugin->examine($email); } return 1; } .. and all the plugins will get a chance in turn to look at it. This can be trivally extended so that plugins could save the email somewhere and then no other plugin should try and do that. Simply have it so that the "examine" method returns 1 if it has saved the email somewhere. You might also wnat to be paranoid and check to see if the plugin has an "examine" method. foreach my $plugin ($self->plugins) { next unless $plugin->can('examine'); last if $plugin->examine($email); } And so on. The sky's the limit. DESCRIPTION Provides a simple but, hopefully, extensible way of having 'plugins' for your module. Obviously this isn't going to be the be all and end all of solutions but it works for me. Essentially all it does is export a method into your namespace that looks through a search path for .pm files and turn those into class names. Optionally it instantiates those classes for you. ADVANCED USAGE Alternatively, if you don't want to use 'plugins' as the method ... package MyClass; use Module::Pluggable sub_name => 'foo'; and then later ... my @plugins = $mc->foo(); Or if you want to look in another namespace package MyClass; use Module::Pluggable search_path => ['Acme::MyClass::Plugin', 'MyClass::Extend']; or directory use Module::Pluggable search_dirs => ['mylibs/Foo']; Or if you want to instantiate each plugin rather than just return the name package MyClass; use Module::Pluggable instantiate => 'new'; and then # whatever is passed to 'plugins' will be passed # to 'new' for each plugin my @plugins = $mc->plugins(@options); alternatively you can just require the module without instantiating it package MyClass; use Module::Pluggable require => 1; since requiring automatically searches inner packages, which may not be desirable, you can turn this off package MyClass; use Module::Pluggable require => 1, inner => 0; You can limit the plugins loaded using the except option, either as a string, array ref or regex package MyClass; use Module::Pluggable except => 'MyClass::Plugin::Foo'; or package MyClass; use Module::Pluggable except => ['MyClass::Plugin::Foo', 'MyClass::Plugin::Bar']; or package MyClass; use Module::Pluggable except => qr/^MyClass::Plugin::(Foo|Bar)$/; and similarly for only which will only load plugins which match. Remember you can use the module more than once package MyClass; use Module::Pluggable search_path => 'MyClass::Filters' sub_name => 'filters'; use Module::Pluggable search_path => 'MyClass::Plugins' sub_name => 'plugins'; and then later ... my @filters = $self->filters; my @plugins = $self->plugins; PLUGIN SEARCHING Every time you call 'plugins' the whole search path is walked again. This allows for dynamically loading plugins even at run time. However this can get expensive and so if you don't expect to want to add new plugins at run time you could do package Foo; use strict; use Module::Pluggable sub_name => '_plugins'; our @PLUGINS; sub plugins { @PLUGINS ||= shift->_plugins } 1; INNER PACKAGES If you have, for example, a file lib/Something/Plugin/Foo.pm that contains package definitions for both "Something::Plugin::Foo" and "Something::Plugin::Bar" then as long as you either have either the require or instantiate option set then we'll also find "Something::Plugin::Bar". Nifty! OPTIONS You can pass a hash of options when importing this module. The options can be ... sub_name The name of the subroutine to create in your namespace. By default this is 'plugins' search_path An array ref of namespaces to look in. search_dirs An array ref of directorys to look in before @INC. instantiate Call this method on the class. In general this will probably be 'new' but it can be whatever you want. Whatever arguments are passed to 'plugins' will be passed to the method. The default is 'undef' i.e just return the class name. require Just require the class, don't instantiate (overrides 'instantiate'); inner If set to 0 will not search inner packages. If set to 1 will override "require". only Takes a string, array ref or regex describing the names of the only plugins to return. Whilst this may seem perverse ... well, it is. But it also makes sense. Trust me. except Similar to "only" it takes a description of plugins to exclude from returning. This is slightly less perverse. package This is for use by extension modules which build on "Module::Pluggable": passing a "package" option allows you to place the plugin method in a different package other than your own. file_regex By default "Module::Pluggable" only looks for *.pm* files. By supplying a new "file_regex" then you can change this behaviour e.g file_regex => qr/\.plugin$/ include_editor_junk By default "Module::Pluggable" ignores files that look like they were left behind by editors. Currently this means files ending in ~ (~), the extensions .swp or .swo, or files beginning with .#. Setting "include_editor_junk" changes "Module::Pluggable" so it does not ignore any files it finds. follow_symlinks Whether, when searching directories, to follow symlinks. Defaults to 1 i.e do follow symlinks. min_depth, max_depth This will allow you to set what 'depth' of plugin will be allowed. So, for example, "MyClass::Plugin::Foo" will have a depth of 3 and "MyClass::Plugin::Foo::Bar" will have a depth of 4 so to only get the former (i.e "MyClass::Plugin::Foo") do package MyClass; use Module::Pluggable max_depth => 3; and to only get the latter (i.e "MyClass::Plugin::Foo::Bar") package MyClass; use Module::Pluggable min_depth => 4; TRIGGERS Various triggers can also be passed in to the options. If any of these triggers return 0 then the plugin will not be returned. before_require Gets passed the plugin name. If 0 is returned then this plugin will not be required either. on_require_error Gets called when there's an error on requiring the plugin. Gets passed the plugin name and the error. The default on_require_error handler is to "carp" the error and return 0. on_instantiate_error Gets called when there's an error on instantiating the plugin. Gets passed the plugin name and the error. The default on_instantiate_error handler is to "carp" the error and return 0. after_require Gets passed the plugin name. If 0 is returned then this plugin will be required but not returned as a plugin. METHODs search_path The method "search_path" is exported into you namespace as well. You can call that at any time to change or replace the search_path. $self->search_path( add => "New::Path" ); # add $self->search_path( new => "New::Path" ); # replace BEHAVIOUR UNDER TEST ENVIRONMENT In order to make testing reliable we exclude anything not from blib if blib.pm is in %INC. However if the module being tested used another module that itself used "Module::Pluggable" then the second module would fail. This was fixed by checking to see if the caller had (^|/)blib/ in their filename. There's an argument that this is the wrong behaviour and that modules should explicitly trigger this behaviour but that particular code has been around for 7 years now and I'm reluctant to change the default behaviour. You can now (as of version 4.1) force Module::Pluggable to look outside blib in a test environment by doing either require Module::Pluggable; $Module::Pluggable::FORCE_SEARCH_ALL_PATHS = 1; import Module::Pluggable; or use Module::Pluggable force_search_all_paths => 1; FUTURE PLANS This does everything I need and I can't really think of any other features I want to add. Famous last words of course Recently tried fixed to find inner packages and to make it 'just work' with PAR but there are still some issues. However suggestions (and patches) are welcome. DEVELOPMENT The master repo for this module is at https://github.com/simonwistow/Module-Pluggable AUTHOR Simon Wistow COPYING Copyright, 2006 Simon Wistow Distributed under the same terms as Perl itself. BUGS None known. SEE ALSO File::Spec, File::Find, File::Basename, Class::Factory::Util, Module::Pluggable::Ordered Module-Pluggable-5.1/lib000755000765000024 012262457022 14665 5ustar00simonstaff000000000000Module-Pluggable-5.1/lib/Devel000755000765000024 012262457022 15724 5ustar00simonstaff000000000000Module-Pluggable-5.1/lib/Devel/InnerPackage.pm000555000765000024 465412262457022 20762 0ustar00simonstaff000000000000package Devel::InnerPackage; use strict; use base qw(Exporter); use vars qw($VERSION @EXPORT_OK); use if $] > 5.017, 'deprecate'; $VERSION = '0.4'; @EXPORT_OK = qw(list_packages); =pod =head1 NAME Devel::InnerPackage - find all the inner packages of a package =head1 SYNOPSIS use Foo::Bar; use Devel::InnerPackage qw(list_packages); my @inner_packages = list_packages('Foo::Bar'); =head1 DESCRIPTION Given a file like this package Foo::Bar; sub foo {} package Foo::Bar::Quux; sub quux {} package Foo::Bar::Quirka; sub quirka {} 1; then list_packages('Foo::Bar'); will return Foo::Bar::Quux Foo::Bar::Quirka =head1 METHODS =head2 list_packages Return a list of all inner packages of that package. =cut sub list_packages { my $pack = shift; $pack .= "::" unless $pack =~ m!::$!; no strict 'refs'; my @packs; my @stuff = grep !/^(main|)::$/, keys %{$pack}; for my $cand (grep /::$/, @stuff) { $cand =~ s!::$!!; my @children = list_packages($pack.$cand); push @packs, "$pack$cand" unless $cand =~ /^::/ || !__PACKAGE__->_loaded($pack.$cand); # or @children; push @packs, @children; } return grep {$_ !~ /::(::ISA::CACHE|SUPER)/} @packs; } ### XXX this is an inlining of the Class-Inspector->loaded() ### method, but inlined to remove the dependency. sub _loaded { my ($class, $name) = @_; no strict 'refs'; # Handle by far the two most common cases # This is very fast and handles 99% of cases. return 1 if defined ${"${name}::VERSION"}; return 1 if @{"${name}::ISA"}; # Are there any symbol table entries other than other namespaces foreach ( keys %{"${name}::"} ) { next if substr($_, -2, 2) eq '::'; return 1 if defined &{"${name}::$_"}; } # No functions, and it doesn't have a version, and isn't anything. # As an absolute last resort, check for an entry in %INC my $filename = join( '/', split /(?:'|::)/, $name ) . '.pm'; return 1 if defined $INC{$filename}; ''; } =head1 AUTHOR Simon Wistow =head1 COPYING Copyright, 2005 Simon Wistow Distributed under the same terms as Perl itself. =head1 BUGS None known. =cut 1; Module-Pluggable-5.1/lib/Module000755000765000024 012262457022 16112 5ustar00simonstaff000000000000Module-Pluggable-5.1/lib/Module/Pluggable.pm000555000765000024 3000112262457022 20524 0ustar00simonstaff000000000000package Module::Pluggable; use strict; use vars qw($VERSION $FORCE_SEARCH_ALL_PATHS); use Module::Pluggable::Object; use if $] > 5.017, 'deprecate'; # ObQuote: # Bob Porter: Looks like you've been missing a lot of work lately. # Peter Gibbons: I wouldn't say I've been missing it, Bob! $VERSION = '5.1'; $FORCE_SEARCH_ALL_PATHS = 0; sub import { my $class = shift; my %opts = @_; my ($pkg, $file) = caller; # the default name for the method is 'plugins' my $sub = $opts{'sub_name'} || 'plugins'; # get our package my ($package) = $opts{'package'} || $pkg; $opts{filename} = $file; $opts{package} = $package; $opts{force_search_all_paths} = $FORCE_SEARCH_ALL_PATHS unless exists $opts{force_search_all_paths}; my $finder = Module::Pluggable::Object->new(%opts); my $subroutine = sub { my $self = shift; return $finder->plugins(@_) }; my $searchsub = sub { my $self = shift; my ($action,@paths) = @_; $finder->{'search_path'} = ["${package}::Plugin"] if ($action eq 'add' and not $finder->{'search_path'} ); push @{$finder->{'search_path'}}, @paths if ($action eq 'add'); $finder->{'search_path'} = \@paths if ($action eq 'new'); return $finder->{'search_path'}; }; my $onlysub = sub { my ($self, $only) = @_; if (defined $only) { $finder->{'only'} = $only; }; return $finder->{'only'}; }; my $exceptsub = sub { my ($self, $except) = @_; if (defined $except) { $finder->{'except'} = $except; }; return $finder->{'except'}; }; no strict 'refs'; no warnings qw(redefine prototype); *{"$package\::$sub"} = $subroutine; *{"$package\::search_path"} = $searchsub; *{"$package\::only"} = $onlysub; *{"$package\::except"} = $exceptsub; } 1; =pod =head1 NAME Module::Pluggable - automatically give your module the ability to have plugins =head1 SYNOPSIS Simple use Module::Pluggable - package MyClass; use Module::Pluggable; and then later ... use MyClass; my $mc = MyClass->new(); # returns the names of all plugins installed under MyClass::Plugin::* my @plugins = $mc->plugins(); =head1 EXAMPLE Why would you want to do this? Say you have something that wants to pass an object to a number of different plugins in turn. For example you may want to extract meta-data from every email you get sent and do something with it. Plugins make sense here because then you can keep adding new meta data parsers and all the logic and docs for each one will be self contained and new handlers are easy to add without changing the core code. For that, you might do something like ... package Email::Examiner; use strict; use Email::Simple; use Module::Pluggable require => 1; sub handle_email { my $self = shift; my $email = shift; foreach my $plugin ($self->plugins) { $plugin->examine($email); } return 1; } .. and all the plugins will get a chance in turn to look at it. This can be trivially extended so that plugins could save the email somewhere and then no other plugin should try and do that. Simply have it so that the C method returns C<1> if it has saved the email somewhere. You might also want to be paranoid and check to see if the plugin has an C method. foreach my $plugin ($self->plugins) { next unless $plugin->can('examine'); last if $plugin->examine($email); } And so on. The sky's the limit. =head1 DESCRIPTION Provides a simple but, hopefully, extensible way of having 'plugins' for your module. Obviously this isn't going to be the be all and end all of solutions but it works for me. Essentially all it does is export a method into your namespace that looks through a search path for .pm files and turn those into class names. Optionally it instantiates those classes for you. =head1 ADVANCED USAGE Alternatively, if you don't want to use 'plugins' as the method ... package MyClass; use Module::Pluggable sub_name => 'foo'; and then later ... my @plugins = $mc->foo(); Or if you want to look in another namespace package MyClass; use Module::Pluggable search_path => ['Acme::MyClass::Plugin', 'MyClass::Extend']; or directory use Module::Pluggable search_dirs => ['mylibs/Foo']; Or if you want to instantiate each plugin rather than just return the name package MyClass; use Module::Pluggable instantiate => 'new'; and then # whatever is passed to 'plugins' will be passed # to 'new' for each plugin my @plugins = $mc->plugins(@options); alternatively you can just require the module without instantiating it package MyClass; use Module::Pluggable require => 1; since requiring automatically searches inner packages, which may not be desirable, you can turn this off package MyClass; use Module::Pluggable require => 1, inner => 0; You can limit the plugins loaded using the except option, either as a string, array ref or regex package MyClass; use Module::Pluggable except => 'MyClass::Plugin::Foo'; or package MyClass; use Module::Pluggable except => ['MyClass::Plugin::Foo', 'MyClass::Plugin::Bar']; or package MyClass; use Module::Pluggable except => qr/^MyClass::Plugin::(Foo|Bar)$/; and similarly for only which will only load plugins which match. Remember you can use the module more than once package MyClass; use Module::Pluggable search_path => 'MyClass::Filters' sub_name => 'filters'; use Module::Pluggable search_path => 'MyClass::Plugins' sub_name => 'plugins'; and then later ... my @filters = $self->filters; my @plugins = $self->plugins; =head1 PLUGIN SEARCHING Every time you call 'plugins' the whole search path is walked again. This allows for dynamically loading plugins even at run time. However this can get expensive and so if you don't expect to want to add new plugins at run time you could do package Foo; use strict; use Module::Pluggable sub_name => '_plugins'; our @PLUGINS; sub plugins { @PLUGINS ||= shift->_plugins } 1; =head1 INNER PACKAGES If you have, for example, a file B that contains package definitions for both C and C then as long as you either have either the B or B option set then we'll also find C. Nifty! =head1 OPTIONS You can pass a hash of options when importing this module. The options can be ... =head2 sub_name The name of the subroutine to create in your namespace. By default this is 'plugins' =head2 search_path An array ref of namespaces to look in. =head2 search_dirs An array ref of directories to look in before @INC. =head2 instantiate Call this method on the class. In general this will probably be 'new' but it can be whatever you want. Whatever arguments are passed to 'plugins' will be passed to the method. The default is 'undef' i.e just return the class name. =head2 require Just require the class, don't instantiate (overrides 'instantiate'); =head2 inner If set to 0 will B search inner packages. If set to 1 will override C. =head2 only Takes a string, array ref or regex describing the names of the only plugins to return. Whilst this may seem perverse ... well, it is. But it also makes sense. Trust me. =head2 except Similar to C it takes a description of plugins to exclude from returning. This is slightly less perverse. =head2 package This is for use by extension modules which build on C: passing a C option allows you to place the plugin method in a different package other than your own. =head2 file_regex By default C only looks for I<.pm> files. By supplying a new C then you can change this behaviour e.g file_regex => qr/\.plugin$/ =head2 include_editor_junk By default C ignores files that look like they were left behind by editors. Currently this means files ending in F<~> (~), the extensions F<.swp> or F<.swo>, or files beginning with F<.#>. Setting C changes C so it does not ignore any files it finds. =head2 follow_symlinks Whether, when searching directories, to follow symlinks. Defaults to 1 i.e do follow symlinks. =head2 min_depth, max_depth This will allow you to set what 'depth' of plugin will be allowed. So, for example, C will have a depth of 3 and C will have a depth of 4 so to only get the former (i.e C) do package MyClass; use Module::Pluggable max_depth => 3; and to only get the latter (i.e C) package MyClass; use Module::Pluggable min_depth => 4; =head1 TRIGGERS Various triggers can also be passed in to the options. If any of these triggers return 0 then the plugin will not be returned. =head2 before_require Gets passed the plugin name. If 0 is returned then this plugin will not be required either. =head2 on_require_error Gets called when there's an error on requiring the plugin. Gets passed the plugin name and the error. The default on_require_error handler is to C the error and return 0. =head2 on_instantiate_error Gets called when there's an error on instantiating the plugin. Gets passed the plugin name and the error. The default on_instantiate_error handler is to C the error and return 0. =head2 after_require Gets passed the plugin name. If 0 is returned then this plugin will be required but not returned as a plugin. =head1 METHODs =head2 search_path The method C is exported into you namespace as well. You can call that at any time to change or replace the search_path. $self->search_path( add => "New::Path" ); # add $self->search_path( new => "New::Path" ); # replace =head1 BEHAVIOUR UNDER TEST ENVIRONMENT In order to make testing reliable we exclude anything not from blib if blib.pm is in %INC. However if the module being tested used another module that itself used C then the second module would fail. This was fixed by checking to see if the caller had (^|/)blib/ in their filename. There's an argument that this is the wrong behaviour and that modules should explicitly trigger this behaviour but that particular code has been around for 7 years now and I'm reluctant to change the default behaviour. You can now (as of version 4.1) force Module::Pluggable to look outside blib in a test environment by doing either require Module::Pluggable; $Module::Pluggable::FORCE_SEARCH_ALL_PATHS = 1; import Module::Pluggable; or use Module::Pluggable force_search_all_paths => 1; =head1 @INC hooks and App::FatPacker If a module's @INC has a hook and that hook is an object which has a C method then we will try and require those files too. See C for an example. This has allowed L (as of version 0.10.0) to provide support for Module::Pluggable. This should also, theoretically, allow someone to modify PAR to do the same thing. =head1 FUTURE PLANS This does everything I need and I can't really think of any other features I want to add. Famous last words of course (not least because we're up to version 5.0 at the time of writing). However suggestions (and patches) are always welcome. =head1 DEVELOPMENT The master repo for this module is at https://github.com/simonwistow/Module-Pluggable =head1 AUTHOR Simon Wistow =head1 COPYING Copyright, 2006 Simon Wistow Distributed under the same terms as Perl itself. =head1 BUGS None known. =head1 SEE ALSO L, L, L, L, L =cut Module-Pluggable-5.1/lib/Module/Pluggable000755000765000024 012262457022 20014 5ustar00simonstaff000000000000Module-Pluggable-5.1/lib/Module/Pluggable/Object.pm000555000765000024 3061612262457022 21746 0ustar00simonstaff000000000000package Module::Pluggable::Object; use strict; use File::Find (); use File::Basename; use File::Spec::Functions qw(splitdir catdir curdir catfile abs2rel); use Carp qw(croak carp confess); use Devel::InnerPackage; use vars qw($VERSION); use if $] > 5.017, 'deprecate'; $VERSION = '5.1'; sub new { my $class = shift; my %opts = @_; return bless \%opts, $class; } ### Eugggh, this code smells ### This is what happens when you keep adding patches ### *sigh* sub plugins { my $self = shift; my @args = @_; # override 'require' $self->{'require'} = 1 if $self->{'inner'}; my $filename = $self->{'filename'}; my $pkg = $self->{'package'}; # Get the exception params instantiated $self->_setup_exceptions; # automatically turn a scalar search path or namespace into a arrayref for (qw(search_path search_dirs)) { $self->{$_} = [ $self->{$_} ] if exists $self->{$_} && !ref($self->{$_}); } # default search path is '::::Plugin' $self->{'search_path'} ||= ["${pkg}::Plugin"]; # default error handler $self->{'on_require_error'} ||= sub { my ($plugin, $err) = @_; carp "Couldn't require $plugin : $err"; return 0 }; $self->{'on_instantiate_error'} ||= sub { my ($plugin, $err) = @_; carp "Couldn't instantiate $plugin: $err"; return 0 }; # default whether to follow symlinks $self->{'follow_symlinks'} = 1 unless exists $self->{'follow_symlinks'}; # check to see if we're running under test my @SEARCHDIR = exists $INC{"blib.pm"} && defined $filename && $filename =~ m!(^|/)blib/! && !$self->{'force_search_all_paths'} ? grep {/blib/} @INC : @INC; # add any search_dir params unshift @SEARCHDIR, @{$self->{'search_dirs'}} if defined $self->{'search_dirs'}; # set our @INC up to include and prefer our search_dirs if necessary my @tmp = @INC; unshift @tmp, @{$self->{'search_dirs'} || []}; local @INC = @tmp if defined $self->{'search_dirs'}; my @plugins = $self->search_directories(@SEARCHDIR); push(@plugins, $self->handle_inc_hooks($_, @SEARCHDIR)) for @{$self->{'search_path'}}; push(@plugins, $self->handle_innerpackages($_)) for @{$self->{'search_path'}}; # return blank unless we've found anything return () unless @plugins; # remove duplicates # probably not necessary but hey ho my %plugins; for(@plugins) { next unless $self->_is_legit($_); $plugins{$_} = 1; } # are we instantiating or requiring? if (defined $self->{'instantiate'}) { my $method = $self->{'instantiate'}; my @objs = (); foreach my $package (sort keys %plugins) { next unless $package->can($method); my $obj = eval { $package->$method(@_) }; $self->{'on_instantiate_error'}->($package, $@) if $@; push @objs, $obj if $obj; } return @objs; } else { # no? just return the names my @objs= sort keys %plugins; return @objs; } } sub _setup_exceptions { my $self = shift; my %only; my %except; my $only; my $except; if (defined $self->{'only'}) { if (ref($self->{'only'}) eq 'ARRAY') { %only = map { $_ => 1 } @{$self->{'only'}}; } elsif (ref($self->{'only'}) eq 'Regexp') { $only = $self->{'only'} } elsif (ref($self->{'only'}) eq '') { $only{$self->{'only'}} = 1; } } if (defined $self->{'except'}) { if (ref($self->{'except'}) eq 'ARRAY') { %except = map { $_ => 1 } @{$self->{'except'}}; } elsif (ref($self->{'except'}) eq 'Regexp') { $except = $self->{'except'} } elsif (ref($self->{'except'}) eq '') { $except{$self->{'except'}} = 1; } } $self->{_exceptions}->{only_hash} = \%only; $self->{_exceptions}->{only} = $only; $self->{_exceptions}->{except_hash} = \%except; $self->{_exceptions}->{except} = $except; } sub _is_legit { my $self = shift; my $plugin = shift; my %only = %{$self->{_exceptions}->{only_hash}||{}}; my %except = %{$self->{_exceptions}->{except_hash}||{}}; my $only = $self->{_exceptions}->{only}; my $except = $self->{_exceptions}->{except}; my $depth = () = split '::', $plugin, -1; return 0 if (keys %only && !$only{$plugin} ); return 0 unless (!defined $only || $plugin =~ m!$only! ); return 0 if (keys %except && $except{$plugin} ); return 0 if (defined $except && $plugin =~ m!$except! ); return 0 if defined $self->{max_depth} && $depth>$self->{max_depth}; return 0 if defined $self->{min_depth} && $depth<$self->{min_depth}; return 1; } sub search_directories { my $self = shift; my @SEARCHDIR = @_; my @plugins; # go through our @INC foreach my $dir (@SEARCHDIR) { push @plugins, $self->search_paths($dir); } return @plugins; } sub search_paths { my $self = shift; my $dir = shift; my @plugins; my $file_regex = $self->{'file_regex'} || qr/\.pm$/; # and each directory in our search path foreach my $searchpath (@{$self->{'search_path'}}) { # create the search directory in a cross platform goodness way my $sp = catdir($dir, (split /::/, $searchpath)); # if it doesn't exist or it's not a dir then skip it next unless ( -e $sp && -d _ ); # Use the cached stat the second time my @files = $self->find_files($sp); # foreach one we've found foreach my $file (@files) { # untaint the file; accept .pm only next unless ($file) = ($file =~ /(.*$file_regex)$/); # parse the file to get the name my ($name, $directory, $suffix) = fileparse($file, $file_regex); next if (!$self->{include_editor_junk} && $self->_is_editor_junk($name)); $directory = abs2rel($directory, $sp); # If we have a mixed-case package name, assume case has been preserved # correctly. Otherwise, root through the file to locate the case-preserved # version of the package name. my @pkg_dirs = (); if ( $name eq lc($name) || $name eq uc($name) ) { my $pkg_file = catfile($sp, $directory, "$name$suffix"); open PKGFILE, "<$pkg_file" or die "search_paths: Can't open $pkg_file: $!"; my $in_pod = 0; while ( my $line = ) { $in_pod = 1 if $line =~ m/^=\w/; $in_pod = 0 if $line =~ /^=cut/; next if ($in_pod || $line =~ /^=cut/); # skip pod text next if $line =~ /^\s*#/; # and comments if ( $line =~ m/^\s*package\s+(.*::)?($name)\s*;/i ) { @pkg_dirs = split /::/, $1 if defined $1;; $name = $2; last; } } close PKGFILE; } # then create the class name in a cross platform way $directory =~ s/^[a-z]://i if($^O =~ /MSWin32|dos/); # remove volume my @dirs = (); if ($directory) { ($directory) = ($directory =~ /(.*)/); @dirs = grep(length($_), splitdir($directory)) unless $directory eq curdir(); for my $d (reverse @dirs) { my $pkg_dir = pop @pkg_dirs; last unless defined $pkg_dir; $d =~ s/\Q$pkg_dir\E/$pkg_dir/i; # Correct case } } else { $directory = ""; } my $plugin = join '::', $searchpath, @dirs, $name; next unless $plugin =~ m!(?:[a-z\d]+)[a-z\d]*!i; $self->handle_finding_plugin($plugin, \@plugins) } # now add stuff that may have been in package # NOTE we should probably use all the stuff we've been given already # but then we can't unload it :( push @plugins, $self->handle_innerpackages($searchpath); } # foreach $searchpath return @plugins; } sub _is_editor_junk { my $self = shift; my $name = shift; # Emacs (and other Unix-y editors) leave temp files ending in a # tilde as a backup. return 1 if $name =~ /~$/; # Emacs makes these files while a buffer is edited but not yet # saved. return 1 if $name =~ /^\.#/; # Vim can leave these files behind if it crashes. return 1 if $name =~ /\.sw[po]$/; return 0; } sub handle_finding_plugin { my $self = shift; my $plugin = shift; my $plugins = shift; my $no_req = shift || 0; return unless $self->_is_legit($plugin); unless (defined $self->{'instantiate'} || $self->{'require'}) { push @$plugins, $plugin; return; } $self->{before_require}->($plugin) || return if defined $self->{before_require}; unless ($no_req) { my $tmp = $@; my $res = eval { $self->_require($plugin) }; my $err = $@; $@ = $tmp; if ($err) { if (defined $self->{on_require_error}) { $self->{on_require_error}->($plugin, $err) || return; } else { return; } } } $self->{after_require}->($plugin) || return if defined $self->{after_require}; push @$plugins, $plugin; } sub find_files { my $self = shift; my $search_path = shift; my $file_regex = $self->{'file_regex'} || qr/\.pm$/; # find all the .pm files in it # this isn't perfect and won't find multiple plugins per file #my $cwd = Cwd::getcwd; my @files = (); { # for the benefit of perl 5.6.1's Find, localize topic local $_; File::Find::find( { no_chdir => 1, follow => $self->{'follow_symlinks'}, wanted => sub { # Inlined from File::Find::Rule C< name => '*.pm' > return unless $File::Find::name =~ /$file_regex/; (my $path = $File::Find::name) =~ s#^\\./##; push @files, $path; } }, $search_path ); } #chdir $cwd; return @files; } sub handle_inc_hooks { my $self = shift; my $path = shift; my @SEARCHDIR = @_; my @plugins; for my $dir ( @SEARCHDIR ) { next unless ref $dir && eval { $dir->can( 'files' ) }; foreach my $plugin ( $dir->files ) { $plugin =~ s/\.pm$//; $plugin =~ s{/}{::}g; next unless $plugin =~ m!^${path}::!; $self->handle_finding_plugin( $plugin, \@plugins ); } } return @plugins; } sub handle_innerpackages { my $self = shift; return () if (exists $self->{inner} && !$self->{inner}); my $path = shift; my @plugins; foreach my $plugin (Devel::InnerPackage::list_packages($path)) { $self->handle_finding_plugin($plugin, \@plugins, 1); } return @plugins; } sub _require { my $self = shift; my $pack = shift; eval "CORE::require $pack"; die ($@) if $@; return 1; } 1; =pod =head1 NAME Module::Pluggable::Object - automatically give your module the ability to have plugins =head1 SYNOPSIS Simple use Module::Pluggable - package MyClass; use Module::Pluggable::Object; my $finder = Module::Pluggable::Object->new(%opts); print "My plugins are: ".join(", ", $finder->plugins)."\n"; =head1 DESCRIPTION Provides a simple but, hopefully, extensible way of having 'plugins' for your module. Obviously this isn't going to be the be all and end all of solutions but it works for me. Essentially all it does is export a method into your namespace that looks through a search path for .pm files and turn those into class names. Optionally it instantiates those classes for you. This object is wrapped by C. If you want to do something odd or add non-general special features you're probably best to wrap this and produce your own subclass. =head1 OPTIONS See the C docs. =head1 AUTHOR Simon Wistow =head1 COPYING Copyright, 2006 Simon Wistow Distributed under the same terms as Perl itself. =head1 BUGS None known. =head1 SEE ALSO L =cut Module-Pluggable-5.1/t000755000765000024 012262457022 14362 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/01use.t000555000765000024 22512262457022 15623 0ustar00simonstaff000000000000#!perl -w use strict; use Test::More tests => 3; use_ok('Module::Pluggable'); use_ok('Module::Pluggable::Object'); use_ok('Devel::InnerPackage'); Module-Pluggable-5.1/t/02alsoworks.t000444000765000024 115612262457022 17075 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 5; my $foo; ok($foo = MyOtherTest->new()); my @plugins; my @expected = qw(MyOtherTest::Plugin::Bar MyOtherTest::Plugin::Foo MyOtherTest::Plugin::Quux MyOtherTest::Plugin::Quux::Foo); ok(@plugins = sort $foo->plugins); is_deeply(\@plugins, \@expected, "is deeply"); @plugins = (); ok(@plugins = sort MyOtherTest->plugins); is_deeply(\@plugins, \@expected, "is deeply class"); package MyOtherTest; use strict; use Module::Pluggable; sub new { my $class = shift; return bless {}, $class; } 1; Module-Pluggable-5.1/t/02works.t000555000765000024 106512262457022 16220 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 5; my $foo; ok($foo = MyTest->new()); my @plugins; my @expected = qw(MyTest::Plugin::Bar MyTest::Plugin::Foo MyTest::Plugin::Quux::Foo); ok(@plugins = sort $foo->plugins); is_deeply(\@plugins, \@expected, "is deeply"); @plugins = (); ok(@plugins = sort MyTest->plugins); is_deeply(\@plugins, \@expected, "is deeply class"); package MyTest; use strict; use Module::Pluggable; sub new { my $class = shift; return bless {}, $class; } 1; Module-Pluggable-5.1/t/02works_taint.t000555000765000024 137612262457022 17424 0ustar00simonstaff000000000000#!perl -wT # NOTE: Module::Pluggable is going into core # and CORE tests can't modify @INC under taint # so this is a work around to make sure it # still works under taint checking. use strict; use Test::More tests => 5; my $foo; ok($foo = MyTest->new()); my @plugins; my @expected = qw(Module::Pluggable::Object); ok(@plugins = sort $foo->plugins); ok(grep {/Module::Pluggable::Object/} @plugins, "Contains Module::Pluggable::Object"); @plugins = (); ok(@plugins = sort MyTest->plugins); ok(grep {/Module::Pluggable::Object/} @plugins, "Contains Module::Pluggable::Object under class method"); package MyTest; use strict; use Module::Pluggable search_path => 'Module::Pluggable'; sub new { my $class = shift; return bless {}, $class; } 1; Module-Pluggable-5.1/t/03diffname.t000555000765000024 70712262457022 16607 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 3; my $foo; ok($foo = MyTest->new()); my @plugins; my @expected = qw(MyTest::Plugin::Bar MyTest::Plugin::Foo MyTest::Plugin::Quux::Foo); ok(@plugins = sort $foo->foo); is_deeply(\@plugins, \@expected); package MyTest; use strict; use Module::Pluggable ( sub_name => 'foo'); sub new { my $class = shift; return bless {}, $class; } 1; Module-Pluggable-5.1/t/04acmedir.t000444000765000024 77012262457022 16440 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 3; my $foo; ok($foo = MyTest->new()); my @plugins; my @expected = qw(Acme::MyTest::Plugin::Foo); ok(@plugins = sort $foo->plugins); is_deeply(\@plugins, \@expected); package MyTest; use File::Spec::Functions qw(catdir); use strict; use Module::Pluggable search_path => ["Acme::MyTest::Plugin"], search_dirs => [ "t/acme" ]; sub new { my $class = shift; return bless {}, $class; } 1; Module-Pluggable-5.1/t/04acmedir_single.t000444000765000024 76312262457022 20003 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 3; my $foo; ok($foo = MyTest->new()); my @plugins; my @expected = qw(Acme::MyTest::Plugin::Foo); ok(@plugins = sort $foo->plugins); is_deeply(\@plugins, \@expected); package MyTest; use File::Spec::Functions qw(catdir); use strict; use Module::Pluggable search_path => "Acme::MyTest::Plugin", search_dirs => "t/acme" ; sub new { my $class = shift; return bless {}, $class; } 1; Module-Pluggable-5.1/t/04acmepath.t000555000765000024 73512262457022 16622 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 3; my $foo; ok($foo = MyTest->new()); my @plugins; my @expected = qw(Acme::MyTest::Plugin::Foo); ok(@plugins = sort $foo->plugins); is_deeply(\@plugins, \@expected); package MyTest; use File::Spec::Functions qw(catdir); use strict; use Module::Pluggable (search_path => ["Acme::MyTest::Plugin"]); sub new { my $class = shift; return bless {}, $class; } 1; Module-Pluggable-5.1/t/04acmepath_single.t000444000765000024 73112262457022 20154 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 3; my $foo; ok($foo = MyTest->new()); my @plugins; my @expected = qw(Acme::MyTest::Plugin::Foo); ok(@plugins = sort $foo->plugins); is_deeply(\@plugins, \@expected); package MyTest; use File::Spec::Functions qw(catdir); use strict; use Module::Pluggable search_path => "Acme::MyTest::Plugin"; sub new { my $class = shift; return bless {}, $class; } 1; Module-Pluggable-5.1/t/05postpath.t000555000765000024 74212262457022 16701 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 3; my $foo; ok($foo = MyTest->new()); my @plugins; my @expected = qw(MyTest::Extend::Plugin::Bar); ok(@plugins = sort $foo->plugins); is_deeply(\@plugins, \@expected); package MyTest; use File::Spec::Functions qw(catdir); use strict; use Module::Pluggable (search_path => ["MyTest::Extend::Plugin"]); sub new { my $class = shift; return bless {}, $class; } 1; Module-Pluggable-5.1/t/06multipath.t000555000765000024 107312262457022 17065 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 3; my $foo; ok($foo = MyTest->new()); my @plugins; my @expected = qw(Acme::MyTest::Plugin::Foo MyTest::Extend::Plugin::Bar); ok(@plugins = sort $foo->plugins); is_deeply(\@plugins, \@expected); package MyTest; use File::Spec::Functions qw(catdir); use strict; use File::Spec::Functions qw(catdir); use Module::Pluggable (search_path => ["MyTest::Extend::Plugin", "Acme::MyTest::Plugin"]); sub new { my $class = shift; return bless {}, $class; } 1; Module-Pluggable-5.1/t/07instantiate.t000555000765000024 146312262457022 17405 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 6; my $foo; ok($foo = MyTest->new()); my @plugins; ok(@plugins = sort $foo->booga(nork => 'fark')); is(ref $plugins[0],'MyTest::Extend::Plugin::Bar'); is($plugins[0]->nork,'fark'); @plugins = (); eval { @plugins = $foo->wooga( nork => 'fark') }; is($@, ''); is(scalar(@plugins),0); package MyTest; use File::Spec::Functions qw(catdir); use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Module::Pluggable (search_path => ["MyTest::Extend::Plugin"], sub_name => 'booga', instantiate => 'new'); use Module::Pluggable (search_path => ["MyTest::Extend::Plugin"], sub_name => 'wooga', instantiate => 'nosomuchmethod'); sub new { my $class = shift; return bless {}, $class; } 1; Module-Pluggable-5.1/t/08nothing.t000555000765000024 72112262457022 16505 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 2; my $foo; ok($foo = MyTest->new()); my @expected = (); my @plugins = sort $foo->plugins; is_deeply(\@plugins, \@expected); package MyTest; use File::Spec::Functions qw(catdir); use strict; use Module::Pluggable (search_path => ["No::Such::Modules"]); use base qw(Module::Pluggable); sub new { my $class = shift; return bless {}, $class; } 1; Module-Pluggable-5.1/t/09require.t000555000765000024 61512262457022 16516 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 2; my $t = MyTest->new(); ok($t->plugins()); ok(keys %{MyTest::Plugin::Foo::}); package MyTest; use File::Spec::Functions qw(catdir); use strict; use Module::Pluggable (require => 1); use base qw(Module::Pluggable); sub new { my $class = shift; return bless {}, $class; } 1; Module-Pluggable-5.1/t/10innerpack.t000444000765000024 112412262457022 17015 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 4; my $t = InnerTest->new(); my %plugins = map { $_ => 1 } $t->plugins; ok(keys %plugins, "Got some plugins"); ok($plugins{'InnerTest::Plugin::Foo'}, "Got Foo"); ok($plugins{'InnerTest::Plugin::Bar'}, "Got Bar - the inner package"); ok($plugins{'InnerTest::Plugin::Quux'}, "Got Quux - the other inner package"); package InnerTest; use strict; use Module::Pluggable require => 1; use base qw(Module::Pluggable); sub new { my $class = shift; return bless {}, $class; } 1; Module-Pluggable-5.1/t/10innerpack_inner.t000444000765000024 100312262457022 20204 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 3; my $t = InnerTest->new(); my %plugins = map { $_ => 1 } $t->plugins; ok(keys %plugins, "Got some plugins"); ok($plugins{'InnerTest::Plugin::Foo'}, "Got Foo"); ok($plugins{'InnerTest::Plugin::Bar'}, "Got Bar - the inner package"); package InnerTest; use strict; use Module::Pluggable inner => 1; use base qw(Module::Pluggable); sub new { my $class = shift; return bless {}, $class; } 1; Module-Pluggable-5.1/t/10innerpack_noinner.t000444000765000024 103112262457022 20542 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 3; my $t = InnerTest->new(); my %plugins = map { $_ => 1 } $t->plugins; ok(keys %plugins, "Got some plugins"); ok($plugins{'InnerTest::Plugin::Foo'}, "Got Foo"); ok(!$plugins{'InnerTest::Plugin::Bar'}, "Didn't get Bar - the inner package"); package InnerTest; use strict; use Module::Pluggable require => 1, inner => 0; use base qw(Module::Pluggable); sub new { my $class = shift; return bless {}, $class; } 1; Module-Pluggable-5.1/t/10innerpack_onefile.t000444000765000024 107712262457022 20525 0ustar00simonstaff000000000000#!perl -wT use strict; use Test::More tests => 2; use Data::Dumper; my $mc = MyClass->new(); my $mc2 = MyClass2->new(); is_deeply([$mc->plugins], [qw(MyClass::Plugin::MyPlugin)], "Got inner plugin"); is_deeply([$mc2->plugins], [], "Didn't get plugin"); package MyClass::Plugin::MyPlugin; sub pretty { print "I am pretty" }; package MyClass; use Module::Pluggable inner => 1; sub new { return bless {}, $_[0] } package MyClass2; use Module::Pluggable search_path => "MyClass::Plugin", inner => 0; sub new { return bless {}, $_[0] } 1; Module-Pluggable-5.1/t/10innerpack_override.t000444000765000024 102112262457022 20710 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 3; my $t = InnerTest->new(); my %plugins = map { $_ => 1 } $t->plugins; ok(keys %plugins, "Got some plugins"); ok($plugins{'InnerTest::Plugin::Foo'}, "Got Foo"); ok($plugins{'InnerTest::Plugin::Bar'}, "Got Bar - the inner package"); package InnerTest; use strict; use Module::Pluggable require => 0, inner => 1; use base qw(Module::Pluggable); sub new { my $class = shift; return bless {}, $class; } 1; Module-Pluggable-5.1/t/10innerpack_super.t000444000765000024 67412262457022 20224 0ustar00simonstaff000000000000#!perl -wT use Test::More tests => 3; use strict; use_ok('Devel::InnerPackage'); Bar->whee; is_deeply([Devel::InnerPackage::list_packages("Bar")],[], "Don't pick up ::SUPER pseudo stash"); is_deeply([Devel::InnerPackage::list_packages("Foo")],['Foo::Bar'], "Still pick up other inner package"); package Foo; sub whee { 1; } package Foo::Bar; sub whee {} package Bar; use base 'Foo'; sub whee { shift->SUPER::whee; 2; } 1; Module-Pluggable-5.1/t/11usetwice.t000444000765000024 135512262457022 16702 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 3; my $foo; ok($foo = MyTest->new()); my @plugins; my @expected = qw(MyTest::Extend::Plugin::Bar MyTest::Plugin::Bar MyTest::Plugin::Foo MyTest::Plugin::Quux::Foo); push @plugins, $foo->plugins; push @plugins, $foo->foo; @plugins = sort @plugins; is_deeply(\@plugins, \@expected); @plugins = (); push @plugins, MyTest->plugins; push @plugins, MyTest->foo; @plugins = sort @plugins; is_deeply(\@plugins, \@expected); package MyTest; use strict; use Module::Pluggable; use Module::Pluggable ( search_path => [ "MyTest::Extend::Plugin" ] , sub_name => 'foo' ); sub new { my $class = shift; return bless {}, $class; } 1; Module-Pluggable-5.1/t/12only.t000444000765000024 204312262457022 16027 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 10; { my $foo; ok($foo = MyTest->new()); my @plugins; my @expected = qw(MyTest::Plugin::Foo); ok(@plugins = sort $foo->plugins); is_deeply(\@plugins, \@expected); @plugins = (); ok(@plugins = sort MyTest->plugins); is_deeply(\@plugins, \@expected); } { my $foo; ok($foo = MyTestSub->new()); my @plugins; my @expected = qw(MyTest::Plugin::Foo); ok(@plugins = sort $foo->plugins); is_deeply(\@plugins, \@expected); @plugins = (); ok(@plugins = sort MyTestSub->plugins); is_deeply(\@plugins, \@expected); } package MyTest; use strict; use Module::Pluggable only => "MyTest::Plugin::Foo"; sub new { my $class = shift; return bless {}, $class; } package MyTestSub; use strict; use Module::Pluggable search_path => "MyTest::Plugin"; sub new { my $class = shift; my $self = bless {}, $class; $self->only("MyTest::Plugin::Foo"); return $self; } 1; Module-Pluggable-5.1/t/12onlyarray.t000444000765000024 205212262457022 17066 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 10; { my $foo; ok($foo = MyTest->new()); my @plugins; my @expected = qw(MyTest::Plugin::Foo); ok(@plugins = sort $foo->plugins); is_deeply(\@plugins, \@expected); @plugins = (); ok(@plugins = sort MyTest->plugins); is_deeply(\@plugins, \@expected); } { my $foo; ok($foo = MyTestSub->new()); my @plugins; my @expected = qw(MyTest::Plugin::Foo); ok(@plugins = sort $foo->plugins); is_deeply(\@plugins, \@expected); @plugins = (); ok(@plugins = sort MyTestSub->plugins); is_deeply(\@plugins, \@expected); } package MyTest; use strict; use Module::Pluggable only => [ "MyTest::Plugin::Foo" ]; sub new { my $class = shift; return bless {}, $class; } package MyTestSub; use strict; use Module::Pluggable search_path => "MyTest::Plugin"; sub new { my $class = shift; my $self = bless {}, $class; $self->only(["MyTest::Plugin::Foo"]); return $self; } 1; Module-Pluggable-5.1/t/12onlyregex.t000444000765000024 205212262457022 17062 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 10; { my $foo; ok($foo = MyTest->new()); my @plugins; my @expected = qw(MyTest::Plugin::Foo); ok(@plugins = sort $foo->plugins); is_deeply(\@plugins, \@expected); @plugins = (); ok(@plugins = sort MyTest->plugins); is_deeply(\@plugins, \@expected); } { my $foo; ok($foo = MyTestSub->new()); my @plugins; my @expected = qw(MyTest::Plugin::Foo); ok(@plugins = sort $foo->plugins); is_deeply(\@plugins, \@expected); @plugins = (); ok(@plugins = sort MyTestSub->plugins); is_deeply(\@plugins, \@expected); } package MyTest; use strict; use Module::Pluggable only => qr/MyTest::Plugin::Foo$/; sub new { my $class = shift; return bless {}, $class; } package MyTestSub; use strict; use Module::Pluggable search_path => "MyTest::Plugin"; sub new { my $class = shift; my $self = bless {}, $class; $self->only(qr/MyTest::Plugin::Foo$/); return $self; } 1; Module-Pluggable-5.1/t/12onlyrequire.t000444000765000024 66412262457022 17413 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 2; my @packages = eval { Zot->_dist_types }; is($@, '', "No warnings"); is(scalar(@packages), 0, "Correctly only got 1 package"); package Zot; use strict; use Module::Pluggable ( sub_name => '_dist_types', search_path => __PACKAGE__, only => qr/Zot::\w+$/, require => 1, ); 1; Module-Pluggable-5.1/t/13except.t000444000765000024 213712262457022 16343 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 10; { my $foo; ok($foo = MyTest->new()); my @plugins; my @expected = qw(MyTest::Plugin::Bar MyTest::Plugin::Quux::Foo); ok(@plugins = sort $foo->plugins); is_deeply(\@plugins, \@expected); @plugins = (); ok(@plugins = sort MyTest->plugins); is_deeply(\@plugins, \@expected); } { my $foo; ok($foo = MyTestSub->new()); my @plugins; my @expected = qw(MyTest::Plugin::Bar MyTest::Plugin::Quux::Foo); ok(@plugins = sort $foo->plugins); is_deeply(\@plugins, \@expected); @plugins = (); ok(@plugins = sort MyTestSub->plugins); is_deeply(\@plugins, \@expected); } package MyTest; use strict; use Module::Pluggable except => "MyTest::Plugin::Foo"; sub new { my $class = shift; return bless {}, $class; } package MyTestSub; use strict; use Module::Pluggable search_path => "MyTest::Plugin"; sub new { my $class = shift; my $self = bless {}, $class; $self->except("MyTest::Plugin::Foo"); return $self; } 1; Module-Pluggable-5.1/t/13exceptarray.t000444000765000024 214612262457022 17402 0ustar00simonstaff000000000000#!perl -wT use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 10; { my $foo; ok($foo = MyTest->new()); my @plugins; my @expected = qw(MyTest::Plugin::Bar MyTest::Plugin::Quux::Foo); ok(@plugins = sort $foo->plugins); is_deeply(\@plugins, \@expected); @plugins = (); ok(@plugins = sort MyTest->plugins); is_deeply(\@plugins, \@expected); } { my $foo; ok($foo = MyTestSub->new()); my @plugins; my @expected = qw(MyTest::Plugin::Bar MyTest::Plugin::Quux::Foo); ok(@plugins = sort $foo->plugins); is_deeply(\@plugins, \@expected); @plugins = (); ok(@plugins = sort MyTestSub->plugins); is_deeply(\@plugins, \@expected); } package MyTest; use strict; use Module::Pluggable except => [ "MyTest::Plugin::Foo" ]; sub new { my $class = shift; return bless {}, $class; } package MyTestSub; use strict; use Module::Pluggable search_path => "MyTest::Plugin"; sub new { my $class = shift; my $self = bless {}, $class; $self->except(["MyTest::Plugin::Foo"]); return $self; } 1; Module-Pluggable-5.1/t/13exceptregex.t000444000765000024 214412262457022 17374 0ustar00simonstaff000000000000#!perl -wT use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 10; { my $foo; ok($foo = MyTest->new()); my @plugins; my @expected = qw(MyTest::Plugin::Bar MyTest::Plugin::Quux::Foo); ok(@plugins = sort $foo->plugins); is_deeply(\@plugins, \@expected); @plugins = (); ok(@plugins = sort MyTest->plugins); is_deeply(\@plugins, \@expected); } { my $foo; ok($foo = MyTestSub->new()); my @plugins; my @expected = qw(MyTest::Plugin::Bar MyTest::Plugin::Quux::Foo); ok(@plugins = sort $foo->plugins); is_deeply(\@plugins, \@expected); @plugins = (); ok(@plugins = sort MyTestSub->plugins); is_deeply(\@plugins, \@expected); } package MyTest; use strict; use Module::Pluggable except => qr/MyTest::Plugin::Foo/; sub new { my $class = shift; return bless {}, $class; } package MyTestSub; use strict; use Module::Pluggable search_path => "MyTest::Plugin"; sub new { my $class = shift; my $self = bless {}, $class; $self->except(qr/MyTest::Plugin::Foo/); return $self; } 1; Module-Pluggable-5.1/t/14package.t000444000765000024 111412262457022 16441 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 5; my $foo; ok($foo = MyTest->new()); my @plugins; my @expected = qw(MyTest::Plugin::Bar MyTest::Plugin::Foo MyTest::Plugin::Quux::Foo); ok(@plugins = sort $foo->plugins); is_deeply(\@plugins, \@expected); @plugins = (); ok(@plugins = sort MyTest->plugins); is_deeply(\@plugins, \@expected); package MyTest; use strict; sub new { return bless {}, $_[0] } package MyOtherTest; use strict; use Module::Pluggable ( package => "MyTest" ); sub new { return bless {}, $_[0] } 1; Module-Pluggable-5.1/t/15topicsafe.t000444000765000024 41412262457022 17006 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More 'no_plan'; use Module::Pluggable search_path => 'Acme::MyTest'; my $topic = "topic"; for ($topic) { main->plugins; } is($topic, 'topic', "we've got the right topic"); Module-Pluggable-5.1/t/16different_extension.t000555000765000024 112712262457022 21121 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 5; my $foo; ok($foo = ExtTest->new()); my @plugins; my @expected = qw(ExtTest::Plugin::Bar ExtTest::Plugin::Foo ExtTest::Plugin::Quux::Foo); ok(@plugins = sort $foo->plugins); is_deeply(\@plugins, \@expected, "is deeply"); @plugins = (); ok(@plugins = sort ExtTest->plugins); is_deeply(\@plugins, \@expected, "is deeply class"); package ExtTest; use strict; use Module::Pluggable file_regex => qr/\.plugin$/; sub new { my $class = shift; return bless {}, $class; } 1; Module-Pluggable-5.1/t/17devel_inner_package.t000444000765000024 44712262457022 21006 0ustar00simonstaff000000000000#!perl -w use Test::More tests => 3; use Devel::InnerPackage qw(list_packages); use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); my @packages; use_ok("TA::C::A::I"); ok(@packages = list_packages("TA::C::A::I")); is_deeply([sort @packages], [qw(TA::C::A::I::A TA::C::A::I::A::B)]); Module-Pluggable-5.1/t/18skipped_package.t000444000765000024 42012262457022 20143 0ustar00simonstaff000000000000#!perl -w use Test::More tests => 1; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Devel::InnerPackage qw(list_packages); use No::Middle; my @p = list_packages("No::Middle"); is_deeply([ sort @p ], [ qw(No::Middle::Package::A No::Middle::Package::B) ]); Module-Pluggable-5.1/t/19can_ok_clobber.t000444000765000024 152612262457022 20004 0ustar00simonstaff000000000000#!/usr/bin/perl use strict; use warnings; use Data::Dumper; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests=>5; #use_ok( 'MyTest' ); #diag "Module::Pluggable::VERSION $Module::Pluggable::VERSION"; my @plugins = sort MyTest->plugins; my @plugins_after; use_ok( 'MyTest::Plugin::Foo' ); ok( my $foo = MyTest::Plugin::Foo->new() ); @plugins_after = MyTest->plugins; is_deeply( \@plugins_after, \@plugins, "plugins haven't been clobbered", ) or diag Dumper(\@plugins_after,\@plugins); can_ok ($foo, 'frobnitz'); @plugins_after = sort MyTest->plugins; is_deeply( \@plugins_after, \@plugins, "plugins haven't been clobbered", ) or diag Dumper(\@plugins_after,\@plugins); package MyTest; use strict; use Module::Pluggable; sub new { my $class = shift; return bless {}, $class; } 1; Module-Pluggable-5.1/t/20dodgy_files.t000555000765000024 321012262457022 17335 0ustar00simonstaff000000000000#!perl -w BEGIN { if ($^O eq 'VMS' || $^O eq 'VOS') { print "1..0 # Skip: can't handle misspelled plugin names\n"; exit; } } use strict; use FindBin; use Test::More; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use File::Spec::Functions qw(catfile); my ($dodgy_file) = (catfile($FindBin::Bin, "lib", "OddTest", "Plugin", "-Dodgy.pm")=~/^(.*)$/); unless (-f $dodgy_file) { plan skip_all => "Can't handle misspelled plugin names\n"; } else { plan tests => 5; } my $foo; ok($foo = OddTest->new()); my @plugins; my @expected = ('OddTest::Plugin::-Dodgy', 'OddTest::Plugin::Foo'); ok(@plugins = sort $foo->plugins); is_deeply(\@plugins, \@expected, "is deeply"); my @odd_plugins; my @odd_expected = qw(OddTest::Plugin::Foo); ok(@odd_plugins = sort $foo->odd_plugins); is_deeply(\@odd_plugins, \@odd_expected, "is deeply"); package OddTest::Pluggable; use Data::Dumper; use base qw(Module::Pluggable::Object); sub find_files { my $self = shift; my @files = $self->SUPER::find_files(@_); return grep { !/(^|\/)-/ } $self->SUPER::find_files(@_) ; } package OddTest; use strict; use Module::Pluggable; sub new { my $class = shift; return bless {}, $class; } sub odd_plugins { my $self = shift; my %opts; my ($pkg, $file) = caller; # the default name for the method is 'plugins' my $sub = $opts{'sub_name'} || 'plugins'; # get our package my ($package) = $opts{'package'} || "OddTest"; $opts{filename} = $file; $opts{package} = $package; my $op = OddTest::Pluggable->new( package => ref($self) ); return $op->plugins(@_); } 1; Module-Pluggable-5.1/t/21editor_junk.t000444000765000024 204212262457022 17362 0ustar00simonstaff000000000000#!perl -w use Test::More; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Module::Pluggable::Object; use File::Spec::Functions qw(catfile); my ($dodgy_file) = (catfile($FindBin::Bin,"lib", "EditorJunk", "Plugin", "#Bar.pm#")=~/^(.*)$/); unless (-f $dodgy_file) { plan skip_all => "Can't handle plugin names with octothorpes\n"; } else { plan tests => 4; } my $foo; ok($foo = EditorJunk->new()); my @plugins; my @expected = qw(EditorJunk::Plugin::Bar EditorJunk::Plugin::Foo); ok(@plugins = sort $foo->plugins); is_deeply(\@plugins, \@expected, "is deeply"); my $mpo = Module::Pluggable::Object->new( package => 'EditorJunk', filename => __FILE__, include_editor_junk => 1, ); @expected = ('EditorJunk::Plugin::.#Bar', 'EditorJunk::Plugin::Bar', 'EditorJunk::Plugin::Foo'); @plugins = sort $mpo->plugins(); is_deeply(\@plugins, \@expected, "is deeply"); package EditorJunk; use strict; use Module::Pluggable; sub new { my $class = shift; return bless {}, $class; } 1; Module-Pluggable-5.1/t/22trigger.t000444000765000024 300112262457022 16505 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 7; my $foo; my @plugins; my @errors; ok($foo = TriggerTest->new(), "Created new TriggerTest"); ok(@plugins = $foo->plugins, "Ran plugins"); ok(@errors = $foo->errors, "Got errors"); is_deeply([sort @plugins], ['TriggerTest::Plugin::After', 'TriggerTest::Plugin::CallbackAllow'], "Got the correct plugins"); is_deeply([@errors], ['TriggerTest::Plugin::Error'], "Got the correct errors"); ok(_is_loaded('TriggerTest::Plugin::CallbackDeny'), "CallbackDeny has been required"); ok(!_is_loaded('TriggerTest::Plugin::Deny'), "Deny has not been required"); # Stolen from Module::Loaded by Chris Williams (bingOs) sub _is_loaded { my $pm = shift; my $file = __PACKAGE__->_pm_to_file( $pm ) or return; return $INC{$file} if exists $INC{$file}; return; } sub _pm_to_file { my $pkg = shift; my $pm = shift or return; my $file = join '/', split '::', $pm; $file .= '.pm'; return $file; } package TriggerTest; our @ERRORS; use strict; use Module::Pluggable require => 1, on_require_error => sub { my $p = shift; push @ERRORS, $p; return 0 }, before_require => sub { my $p = shift; return !($p eq "TriggerTest::Plugin::Deny") }, after_require => sub { my $p = shift; return !($p->can('exclude') && $p->exclude) }; sub new { my $class = shift; return bless {}, $class; } sub errors { @ERRORS; } 1; Module-Pluggable-5.1/t/23depth.t000444000765000024 155712262457022 16165 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 2; my $min = MinTest->new(); my $max = MaxTest->new(); is_deeply([sort qw(MyOtherTest::Plugin::Bar MyOtherTest::Plugin::Foo MyOtherTest::Plugin::Quux)], [sort $max->plugins], "min depth"); is_deeply([qw(MyOtherTest::Plugin::Quux::Foo)], [sort $min->plugins], "max depth"); package MinTest; use File::Spec::Functions qw(catdir); use strict; use File::Spec::Functions qw(catdir); use Module::Pluggable search_path => "MyOtherTest::Plugin", min_depth => 4; sub new { my $class = shift; return bless {}, $class; } package MaxTest; use File::Spec::Functions qw(catdir); use strict; use File::Spec::Functions qw(catdir); use Module::Pluggable search_path => "MyOtherTest::Plugin", max_depth => 3; sub new { my $class = shift; return bless {}, $class; } 1;Module-Pluggable-5.1/t/24local_inc_object.t000444000765000024 126712262457022 20331 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use Test::More tests => 2; eval { require 'Text::BibTex' }; my $bibtex = !$@; SKIP: { skip "This test fails when Text::BibTex is installed", 2 if $bibtex; my $inc = IncTest->new(); my ($ta) = grep { ref($_) eq 'Text::Abbrev'} eval { local ($^W) = 0; $inc->plugins }; ok($ta); is($ta->MPCHECK, "HELLO"); }; package IncTest; use Module::Pluggable search_path => "Text", search_dirs => "t/lib", instantiate => 'module_pluggable', on_require_error => sub { }, on_instantiate_error => sub { }; sub new { my $class = shift; return bless {}, $class; } 1; Module-Pluggable-5.1/t/24local_inc_package.t000444000765000024 65712262457022 20440 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use Test::More tests => 1; eval { require 'Text::BibTex' }; my $bibtex = !$@; SKIP: { skip "This test fails when Text::BibTex is installed", 2 if $bibtex; IncTest->new()->plugins; is(Text::Abbrev->MPCHECK, "HELLO"); } package IncTest; use Module::Pluggable search_path => "Text", search_dirs => "t/lib", require => 1; sub new { my $class = shift; return bless {}, $class; } 1;Module-Pluggable-5.1/t/25single_letter_package.t000555000765000024 77412262457022 21361 0ustar00simonstaff000000000000#!perl -w use strict; use FindBin; use lib (($FindBin::Bin."/lib")=~/^(.*)$/); use Test::More tests => 5; my $foo; ok($foo = M->new()); my @plugins; my @expected = qw(M::X); ok(@plugins = sort $foo->plugins); is_deeply(\@plugins, \@expected, "is deeply"); @plugins = (); ok(@plugins = sort M->plugins); is_deeply(\@plugins, \@expected, "is deeply class"); package M; use strict; use Module::Pluggable search_path => "M"; sub new { my $class = shift; return bless {}, $class; } 1; Module-Pluggable-5.1/t/26inc_hook.t000555000765000024 121712262457022 16651 0ustar00simonstaff000000000000#!perl -w use strict; use Test::More tests => 2; my @plugins = Foo->plugins; is($plugins[0], 'IncHook::Test', "found module"); is($plugins[0]->found_it, 'IncHook::Test', "ran module"); package IncHook; use strict; sub new { return bless {}, shift } sub IncHook::INC { my ($self, $filename) = @_; return unless $filename eq 'IncHook/Test.pm'; my @sub = ('package IncHook::Test; sub found_it { return __PACKAGE__ }; 1;'); return sub { defined($_ = shift @sub) }; } sub files { qw(IncHook/Test.pm) } package Foo; use strict; use Module::Pluggable require => 1, search_path => 'IncHook'; BEGIN { unshift @INC, IncHook->new }; 1;Module-Pluggable-5.1/t/27app_fatpacker.t000555000765000024 357012262457022 17665 0ustar00simonstaff000000000000#!perl use strict; use warnings; use Test::More; BEGIN { my $need_version = "0.10.0"; eval "use App::FatPacker $need_version ; 1; " or plan skip_all => "App::FatPacker >= $need_version not available"; } use Cwd 'cwd'; use File::Temp; use File::Copy; use File::Find; use File::Path 'mkpath'; # use legacy interface for backwards compatibility use File::Spec::Functions qw(catdir catfile splitdir); # prepare directory for App::FatPacker my $testdir = File::Temp->newdir; my $fatlib = catdir($testdir->dirname, 'fatlib'); # copy our Module::Pluggable to $tempdir/fatlib mkpath $fatlib; copy_dir('lib', $fatlib, 1); # Copy the test application and its plugins to $tempdir/lib copy_dir(catdir('t', 'fp'), $testdir->dirname, 2); # fatpack it. fatpacker requires files be in the current directory my $cwd = cwd; my $packed = eval { chdir $testdir or die "unable to chdir to $testdir\n"; my $fp = App::FatPacker->new; $fp->fatpack_file('app.pl'); }; my $err = $@; chdir $cwd; BAIL_OUT("error fatpacking test application: $err") if $@; # write packed application to a file outside of the test dir to # make sure there's no way it can see its modules my $packed_file = File::Temp->new; $packed_file->print($packed); $packed_file->close; # run it (and it's included tests ) require_ok $packed_file; done_testing; sub copy_dir { my ($from, $to, $shift) = @_; find( sub { my @p = splitdir($File::Find::dir); splice(@p, 0, $shift); my $ddir = catdir($to, @p); if (-d $_) { $ddir = catdir($ddir, $_); mkpath $ddir unless -d $ddir; } else { unless (copy($_, $ddir)) { my $file = catfile( $File::Find::dir, $_ ); die "error copying $file to $ddir: $!\n"; } } }, $from ); } Module-Pluggable-5.1/t/acme000755000765000024 012262457022 15267 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/acme/Acme000755000765000024 012262457022 16134 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/acme/Acme/MyTest000755000765000024 012262457022 17361 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/acme/Acme/MyTest/Plugin000755000765000024 012262457022 20617 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/acme/Acme/MyTest/Plugin/Foo.pm000444000765000024 7012262457022 21772 0ustar00simonstaff000000000000package Acme::MyTest::Plugin::Foo; use strict; 1; Module-Pluggable-5.1/t/fp000755000765000024 012262457022 14767 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/fp/app.pl000444000765000024 37012262457022 16221 0ustar00simonstaff000000000000#!/usr/bin/env perl use strict; use warnings; use Test::More; my @plugins = App::TestMPFP->plugins(); is_deeply([@plugins], ['App::TestMPFP::Plugin::A'], 'found expected plugins'); package App::TestMPFP; use Module::Pluggable require => 1; 1; Module-Pluggable-5.1/t/fp/lib000755000765000024 012262457022 15535 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/fp/lib/App000755000765000024 012262457022 16255 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/fp/lib/App/TestMPFP000755000765000024 012262457022 17657 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/fp/lib/App/TestMPFP/Plugin000755000765000024 012262457022 21115 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/fp/lib/App/TestMPFP/Plugin/A.pm000444000765000024 4512262457022 21727 0ustar00simonstaff000000000000package App::TestMPFP::Plugin::A; 1; Module-Pluggable-5.1/t/lib000755000765000024 012262457022 15130 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/Acme000755000765000024 012262457022 15775 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/Acme/Foo-Bar.pm000444000765000024 6112262457022 17652 0ustar00simonstaff000000000000package Acme::FooBar; our $quux = "hello"; 1; Module-Pluggable-5.1/t/lib/Acme/MyTest000755000765000024 012262457022 17222 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/Acme/MyTest/Plugin000755000765000024 012262457022 20460 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/Acme/MyTest/Plugin/Foo.pm000555000765000024 7012262457022 21636 0ustar00simonstaff000000000000package Acme::MyTest::Plugin::Foo; use strict; 1; Module-Pluggable-5.1/t/lib/EditorJunk000755000765000024 012262457022 17206 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/EditorJunk/Plugin000755000765000024 012262457022 20444 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/EditorJunk/Plugin/Bar.pm000444000765000024 5612262457022 21604 0ustar00simonstaff000000000000package EditorJunk::Bar; use strict; 1; Module-Pluggable-5.1/t/lib/EditorJunk/Plugin/Bar.pm.swo000444000765000024 5612262457022 22413 0ustar00simonstaff000000000000package EditorJunk::Bar; use strict; 1; Module-Pluggable-5.1/t/lib/EditorJunk/Plugin/Bar.pm.swp000444000765000024 5612262457022 22414 0ustar00simonstaff000000000000package EditorJunk::Bar; use strict; 1; Module-Pluggable-5.1/t/lib/EditorJunk/Plugin/Bar.pm~000444000765000024 5612262457022 22002 0ustar00simonstaff000000000000package EditorJunk::Bar; use strict; 1; Module-Pluggable-5.1/t/lib/EditorJunk/Plugin/Foo.pm000444000765000024 5612262457022 21623 0ustar00simonstaff000000000000package EditorJunk::Foo; use strict; 1; Module-Pluggable-5.1/t/lib/ExtTest000755000765000024 012262457022 16530 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/ExtTest/Plugin000755000765000024 012262457022 17766 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/ExtTest/Plugin/Bar.plugin000555000765000024 6212262457022 22010 0ustar00simonstaff000000000000package MyTest::Plugin::Bar; use strict; 1; Module-Pluggable-5.1/t/lib/ExtTest/Plugin/Foo.plugin000555000765000024 6212262457022 22027 0ustar00simonstaff000000000000package MyTest::Plugin::Foo; use strict; 1; Module-Pluggable-5.1/t/lib/ExtTest/Plugin/Quux000755000765000024 012262457022 20730 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/ExtTest/Plugin/Quux/Foo.plugin000555000765000024 7012262457022 22770 0ustar00simonstaff000000000000package MyTest::Plugin::Quux::Foo; use strict; 1; Module-Pluggable-5.1/t/lib/InnerTest000755000765000024 012262457022 17043 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/InnerTest/Plugin000755000765000024 012262457022 20301 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/InnerTest/Plugin/Foo.pm000444000765000024 31512262457022 21476 0ustar00simonstaff000000000000package InnerTest::Plugin::Foo; use strict; our $FOO = 1; package InnerTest::Plugin::Bar; use strict; sub bar {} package InnerTest::Plugin::Quux; use strict; use base qw(InnerTest::Plugin::Bar); 1; Module-Pluggable-5.1/t/lib/M000755000765000024 012262457022 15324 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/M/X.pm000444000765000024 12312262457022 16202 0ustar00simonstaff000000000000package M::X; use strict; sub new { return bless {}, $_[0]; } sub frobnitz {} 1; Module-Pluggable-5.1/t/lib/MyOtherTest000755000765000024 012262457022 17357 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/MyOtherTest/Plugin000755000765000024 012262457022 20615 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/MyOtherTest/Plugin/Bar.pm000444000765000024 6312262457022 21753 0ustar00simonstaff000000000000package MyOtherTest::Plugin::Bar; use strict; 1; Module-Pluggable-5.1/t/lib/MyOtherTest/Plugin/Foo.pm000444000765000024 6312262457022 21772 0ustar00simonstaff000000000000package MyOtherTest::Plugin::Foo; use strict; 1; Module-Pluggable-5.1/t/lib/MyOtherTest/Plugin/Quux.pm000444000765000024 6412262457022 22212 0ustar00simonstaff000000000000package MyOtherTest::Plugin::Quux; use strict; 1; Module-Pluggable-5.1/t/lib/MyOtherTest/Plugin/Quux000755000765000024 012262457022 21557 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/MyOtherTest/Plugin/Quux/Foo.pm000444000765000024 7112262457022 22733 0ustar00simonstaff000000000000package MyOtherTest::Plugin::Quux::Foo; use strict; 1; Module-Pluggable-5.1/t/lib/MyTest000755000765000024 012262457022 16355 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/MyTest/Extend000755000765000024 012262457022 17604 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/MyTest/Extend/Plugin000755000765000024 012262457022 21042 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/MyTest/Extend/Plugin/Bar.pm000555000765000024 25612262457022 22227 0ustar00simonstaff000000000000package MyTest::Extend::Plugin::Bar; use strict; sub new { my $class = shift; my %self = @_; return bless \%self, $class; } sub nork { return $_[0]->{'nork'}; } 1; Module-Pluggable-5.1/t/lib/MyTest/Plugin000755000765000024 012262457022 17613 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/MyTest/Plugin/Bar.pm000555000765000024 6212262457022 20753 0ustar00simonstaff000000000000package MyTest::Plugin::Bar; use strict; 1; Module-Pluggable-5.1/t/lib/MyTest/Plugin/Foo.pm000555000765000024 14512262457022 21014 0ustar00simonstaff000000000000package MyTest::Plugin::Foo; use strict; sub new { return bless {}, $_[0]; } sub frobnitz {} 1; Module-Pluggable-5.1/t/lib/MyTest/Plugin/Quux000755000765000024 012262457022 20555 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/MyTest/Plugin/Quux/Foo.pm000555000765000024 7012262457022 21733 0ustar00simonstaff000000000000package MyTest::Plugin::Quux::Foo; use strict; 1; Module-Pluggable-5.1/t/lib/No000755000765000024 012262457022 15504 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/No/Middle.pm000444000765000024 17712262457022 17362 0ustar00simonstaff000000000000package No::Middle; sub foo {} package No::Middle::Package::A; sub foo {} package No::Middle::Package::B; sub foo {} 1; Module-Pluggable-5.1/t/lib/OddTest000755000765000024 012262457022 16476 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/OddTest/Plugin000755000765000024 012262457022 17734 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/OddTest/Plugin/Foo.pm000444000765000024 5712262457022 21114 0ustar00simonstaff000000000000package OddFiles/Plugin/Foo.pm sub new {} 1; Module-Pluggable-5.1/t/lib/TA000755000765000024 012262457022 15434 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/TA/C000755000765000024 012262457022 15616 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/TA/C/A000755000765000024 012262457022 15776 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/TA/C/A/I.pm000444000765000024 16512262457022 16643 0ustar00simonstaff000000000000package TA::C::A::I; sub foo { } package TA::C::A::I::A; sub foo { } package TA::C::A::I::A::B; sub foo { } 1; Module-Pluggable-5.1/t/lib/Text000755000765000024 012262457022 16054 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/Text/Abbrev.pm000444000765000024 16412262457022 17731 0ustar00simonstaff000000000000package Text::Abbrev; use strict; sub module_pluggable { return bless {}, shift; } sub MPCHECK { "HELLO" } 1;Module-Pluggable-5.1/t/lib/TriggerTest000755000765000024 012262457022 17373 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/TriggerTest/Plugin000755000765000024 012262457022 20631 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/TriggerTest/Plugin/After.pm000444000765000024 4712262457022 22326 0ustar00simonstaff000000000000package TriggerTest::Plugin::After; 1;Module-Pluggable-5.1/t/lib/TriggerTest/Plugin/CallbackAllow.pm000444000765000024 11512262457022 23774 0ustar00simonstaff000000000000package TriggerTest::Plugin::CallbackAllow; sub exclude { return 0; } 1;Module-Pluggable-5.1/t/lib/TriggerTest/Plugin/CallbackDeny.pm000444000765000024 11412262457022 23614 0ustar00simonstaff000000000000package TriggerTest::Plugin::CallbackDeny; sub exclude { return 1; } 1;Module-Pluggable-5.1/t/lib/TriggerTest/Plugin/Deny.pm000444000765000024 4612262457022 22163 0ustar00simonstaff000000000000package TriggerTest::Plugin::Deny; 1;Module-Pluggable-5.1/t/lib/TriggerTest/Plugin/Error.pm000444000765000024 4512262457022 22354 0ustar00simonstaff000000000000package TriggerTest::Plugin::Error; Module-Pluggable-5.1/t/lib/Zot000755000765000024 012262457022 15704 5ustar00simonstaff000000000000Module-Pluggable-5.1/t/lib/Zot/.Zork.pm000444000765000024 012262457022 17310 0ustar00simonstaff000000000000