Subject: | Singleton settings behaviour |
I'm not sure if this is a feature, a bug, and oversight, or just wrong expectations.
When creating a new instance of a module that uses Module::Pluggable, one might expect that the settings set by using search_path() on the module instance, [and only()/except() from my patch] would be reset. This isn't the case since my %opts in import() is shared among all of the autogenerated methods (search_path/only/except) in the package namespace itself.
The attached script demonstrates the problem in its simplest form. If I set a search_path() on the first instance, it's values are there for the second instance. In essence, there's no clear way to reset any of those values in %opts. Once an option is set, it's set for all instances of the module using Module::Pluggable. I think that means for all instances in the scope of a pl file, and all nistances in the scope of an apache child process under mod_perl.
This cropped up in Handel, where the Handel::Checkout module can act on different plugins/namespaces in every instance created by new(). This wasn't so apparent until I changed the order of tests in the test file and noticed %opts data overlapping. I'd assume that if the only*.t and except*.t tests in the M::P dist were combined, they would show the same problem.
At this point, I'm not sure what to do about it. Once M::P has been used in a module namespace, there's no way to actually reset the options between instances. Should a reset() method be created that set the %opts in import() back to the defaults? Or, should the options be moved into the instance hash itself? That seems risky since modules that use M::P could just as well be blessed arrays or blessed scalars, and not blessed hashes.
I'm willing to take a crack at patching things up, I'm just not sure what fix is best given the goals of M::P.
#!/usr/bin/perl
use strict;
use lib './lib';
use lib './t/lib';
my $test = MyTest->new();
$test->search_path(add => 'Foo');
#prints Foo
warn @{$test->search_path};
my $othertest = MyTest->new();
#still has Foo
warn @{$othertest->search_path};
package MyTest;
use strict;
use Module::Pluggable;
sub new {bless {}, shift};
1;