Skip Menu |

This queue is for tickets about the Module-Pluggable CPAN distribution.

Report information
The Basics
Id: 23616
Status: rejected
Priority: 0/
Queue: Module-Pluggable

People
Owner: simonw [...] cpan.org
Requestors: geoff [...] laxan.com
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 3.3
Fixed in: (no value)



Subject: Patch to add new option 'include_root_module'
Hi, Attached is a patch which adds a new option to Module::Pluggable::Object to include the 'root' module, by which I mean the one named the same as the search path, to the plugins returned. There's one particular thing I'm working with that this would be really useful for. We're using this module to find classes which implement bits of a website, each of which handles different URLs. For example we might have something like this: Example.pm Example/Foo.pm Example/Foo/Bar.pm So URLs like "/foo/bar/..." get passed to the last module, and so on. But the Example module itself has to provide the code for the homepage at "/", so we need to include that as a plugin. My patch does this if you pass in an option 'include_root_module' with a true value. Without that the behaviour is unchanged. My patch includes a new test file and a new test module for it to find.
Subject: module-pluggable-include-root.diff
diff -urN Module-Pluggable-3.3.orig/MANIFEST Module-Pluggable-3.3/MANIFEST --- Module-Pluggable-3.3.orig/MANIFEST 2006-11-24 15:43:38.000000000 +0000 +++ Module-Pluggable-3.3/MANIFEST 2006-11-25 19:21:15.000000000 +0000 @@ -41,6 +41,7 @@ t/18skipped_package.t t/19can_ok_clobber.t t/20dodgy_files.t +t/21object.t t/acme/Acme/MyTest/Plugin/Foo.pm t/lib/Acme/MyTest/Plugin/Foo.pm t/lib/ExtTest/Plugin/Bar.plugin @@ -52,6 +53,7 @@ t/lib/MyOtherTest/Plugin/Quux.pm t/lib/MyOtherTest/Plugin/Quux/Foo.pm t/lib/MyTest/Extend/Plugin/Bar.pm +t/lib/MyTest/Plugin.pm t/lib/MyTest/Plugin/Bar.pm t/lib/MyTest/Plugin/Foo.pm t/lib/MyTest/Plugin/Quux/Foo.pm diff -urN Module-Pluggable-3.3.orig/lib/Module/Pluggable/Object.pm Module-Pluggable-3.3/lib/Module/Pluggable/Object.pm --- Module-Pluggable-3.3.orig/lib/Module/Pluggable/Object.pm 2006-11-24 15:43:38.000000000 +0000 +++ Module-Pluggable-3.3/lib/Module/Pluggable/Object.pm 2006-11-25 19:19:07.000000000 +0000 @@ -140,6 +140,12 @@ my @files = $self->find_files($sp); + if ($self->{'include_root_module'}) { + my $filename = "$sp.pm"; + unshift @files, $filename + if -f $filename; + } + # foreach one we've found foreach my $file (@files) { # untaint the file; accept .pm only @@ -147,6 +153,8 @@ # parse the file to get the name my ($name, $directory) = fileparse($file, $file_regex); + my @module = splitdir catdir($searchpath); + $directory = abs2rel($directory, $sp); # then create the class name in a cross platform way $directory =~ s/^[a-z]://i if($^O =~ /MSWin32|dos/); # remove volume @@ -155,7 +163,12 @@ } else { $directory = ""; } - my $plugin = join "::", splitdir catdir($searchpath, $directory, $name); + + push @module, splitdir catdir $directory + unless $directory eq '' || $directory eq '..'; + push @module, $name + unless $directory eq '..'; + my $plugin = join "::", @module; next unless $plugin =~ m!(?:[a-z\d]+)[a-z\d]!i; diff -urN Module-Pluggable-3.3.orig/t/21object.t Module-Pluggable-3.3/t/21object.t --- Module-Pluggable-3.3.orig/t/21object.t 1970-01-01 01:00:00.000000000 +0100 +++ Module-Pluggable-3.3/t/21object.t 2006-11-25 19:19:06.000000000 +0000 @@ -0,0 +1,32 @@ +#!perl -w + +use strict; +use FindBin; +use lib "$FindBin::Bin/lib"; +use Test::More tests => 9; + +my $foo; +ok($foo = MyTest->new(package => 'MyTest')); +my @plugins; +ok(@plugins = sort $foo->plugins); +my @expected = qw(MyTest::Plugin::Bar MyTest::Plugin::Foo + MyTest::Plugin::Quux::Foo); +is_deeply(\@plugins, \@expected, "sublcass of ::Object"); + +# Test with custom 'search_path' value. +ok($foo = MyTest->new(search_path => 'MyTest::Plugin::Quux')); +ok(@plugins = sort $foo->plugins); +@expected = qw(MyTest::Plugin::Quux::Foo); +is_deeply(\@plugins, \@expected, "custom search_path"); + +# Test with the 'include_root_module' option. +ok($foo = MyTest->new(package => 'MyTest', include_root_module => 1)); +ok(@plugins = sort $foo->plugins); +@expected = qw(MyTest::Plugin MyTest::Plugin::Bar MyTest::Plugin::Foo + MyTest::Plugin::Quux::Foo); +is_deeply(\@plugins, \@expected, "include_root_module turned on"); + + +package MyTest; + +use base qw(Module::Pluggable::Object); diff -urN Module-Pluggable-3.3.orig/t/lib/MyTest/Plugin.pm Module-Pluggable-3.3/t/lib/MyTest/Plugin.pm --- Module-Pluggable-3.3.orig/t/lib/MyTest/Plugin.pm 1970-01-01 01:00:00.000000000 +0100 +++ Module-Pluggable-3.3/t/lib/MyTest/Plugin.pm 2006-11-25 18:14:39.000000000 +0000 @@ -0,0 +1,5 @@ +package MyTest::Plugin; + +use strict; + +1;
On Sat Nov 25 14:30:17 2006, GEOFFR wrote: Show quoted text
> My patch includes a new test file and a new test module for it to find.
My apologies for taking so long to reply to this. I'm inclined not to accept the patch, sorry. Thanks for putting so much effort in it but I'm trying to reduce the number of options for Module::Pluggable and this is a fairly niche case that could more easily be accomplished by either subclassing Module::Pluggable::Object or Module::Pluggable or simply wrapping the 'plugins' method something like this ... package Foo; use Module::Pluggable sub_name => '_plugins'; sub plugins { (__PACKAGE__, shift->_plugins); } 1; Again, my apologies. And thanks for the patch. If you feel that I'm wrong I'm perfectly happy to be argued with :) Simon