Skip to content

Commit

Permalink
Add a new 'on_instantiate_error' trigger, rename 'on_error' to 'on_re…
Browse files Browse the repository at this point in the history
…quire_error' and clean up some test failures when real world modules do kooky things.
  • Loading branch information
Simon Wistow committed Aug 13, 2012
1 parent 4dde0f7 commit 0ec1af3
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 13 deletions.
12 changes: 10 additions & 2 deletions lib/Module/Pluggable.pm
Original file line number Diff line number Diff line change
Expand Up @@ -358,13 +358,21 @@ Gets passed the plugin name.
If 0 is returned then this plugin will not be required either.
=head2 on_error <plugin> <err>
=head2 on_require_error <plugin> <err>
Gets called when there's an error on requiring the plugin.
Gets passed the plugin name and the error.
The default on_error handler is to C<carp> the error and return 0.
The default on_require_error handler is to C<carp> the error and return 0.
=head2 on_instantiate_error <plugin> <err>
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<carp> the error and return 0.
=head2 after_require <plugin>
Expand Down
17 changes: 13 additions & 4 deletions lib/Module/Pluggable/Object.pm
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ sub new {

sub plugins {
my $self = shift;
my @args = @_;

# override 'require'
$self->{'require'} = 1 if $self->{'inner'};
Expand All @@ -45,7 +46,8 @@ sub plugins {
$self->{'search_path'} ||= ["${pkg}::Plugin"];

# default error handler
$self->{'on_error'} ||= sub { my ($plugin, $err) = @_; carp "Couldn't require $plugin : $err"; return 0 };
$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'};
Expand Down Expand Up @@ -78,7 +80,14 @@ sub plugins {
# are we instantiating or requring?
if (defined $self->{'instantiate'}) {
my $method = $self->{'instantiate'};
return map { $_->can($method) ? $_->$method(@_) : () } keys %plugins;
my @objs = ();
foreach my $package (keys %plugins) {
next unless $package->can($method);
my $obj = eval { $package->new(@_) };
$self->{'on_instantiate_error'}->($package, $@) if $@;
push @objs, $obj if $obj;
}
return @objs;
} else {
# no? just return the names
return keys %plugins;
Expand Down Expand Up @@ -271,8 +280,8 @@ sub handle_finding_plugin {
my $err = $@;
$@ = $tmp;
if ($err) {
if (defined $self->{on_error}) {
$self->{on_error}->($plugin, $err) || return;
if (defined $self->{on_require_error}) {
$self->{on_require_error}->($plugin, $err) || return;
} else {
return;
}
Expand Down
8 changes: 4 additions & 4 deletions t/22trigger.t
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ package TriggerTest;

our @ERRORS;
use strict;
use Module::Pluggable require => 1,
on_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) };
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;
Expand Down
6 changes: 3 additions & 3 deletions t/24local_inc_object.t
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ use FindBin;
use Test::More tests => 2;

my $inc = IncTest->new();
my ($ta) = grep { ref($_) eq 'Text::Abbrev'} $inc->plugins;
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 => 'new';
use Module::Pluggable search_path => "Text", search_dirs => "t/lib", instantiate => 'new', on_instantiate_error => sub {};

sub new {
my $class = shift;
return bless {}, $class;
}
1;
1;

0 comments on commit 0ec1af3

Please sign in to comment.