Subject: | [PATCH] Cache usable_classes to avoid "Attempt to reload" exception |
First, thanks for the module.
When _try_load is called twice on a Watcher subclass which fails to load
an "Attempt to reload" exception is fired that isn't caught. This
happens when you create multiple watchers and one of the Watcher
subclasses won't compile on your system (ie, Inotify on a system without
Linux::Inotify2).
This patch caches usable_classes and then uses the result to determine
which Watcher subclass to use.
To reproduce:
$ perl -MTest::Without::Module=Linux::Inotify2 -w -Ilib t/instantiate.t
1..2
Could not load class (File::ChangeNotify::Watcher::Inotify) because :
Attempt to reload File/ChangeNotify/Watcher/Inotify.pm aborted.
Compilation failed in require at
/opt/local/lib/perl5/site_perl/5.10.1/darwin-thread-multi-2level/Class/MOP.pm
line 129.
at
/opt/local/lib/perl5/site_perl/5.10.1/darwin-thread-multi-2level/Class/MOP.pm
line 114
Class::MOP::load_first_existing_class('File::ChangeNotify::Watcher::Inotify') called at /opt/local/lib/perl5/site_perl/5.10.1/darwin-thread-multi-2level/Class/MOP.pm line 135
Class::MOP::load_class('File::ChangeNotify::Watcher::Inotify') called
at lib/File/ChangeNotify.pm line 34
eval {...} called at lib/File/ChangeNotify.pm line 34
File::ChangeNotify::_try_load('File::ChangeNotify::Watcher::Inotify')
called at lib/File/ChangeNotify.pm line 16
File::ChangeNotify::instantiate_watcher('File::ChangeNotify',
'directories', 'ARRAY(0x100803d38)') called at t/instantiate.t line 6
-Mark
Subject: | 0001-Patch-to-cache-usable_classes-to-avoid-reload-attemp.patch |
From 3dd2194dfcdf7b1b040cfaf19176581ce7251c98 Mon Sep 17 00:00:00 2001
From: Mark Grimes <mgrimes@satch.grimes.homeip.net>
Date: Sun, 6 Dec 2009 12:14:13 -0500
Subject: [PATCH] Patch to cache usable_classes to avoid reload attempt exception
When _try_load is called twice on a Watcher subclass which fails to
load an "Attempt to reload" exception is fired that isn't caught.
This happens when you create multiple watchers and one of the
Watcher subclasses won't compile on your system (ie, Inotify on a
system without Linux::Inotify2).
To reproduce:
$ perl -MTest::Without::Module=Linux::Inotify2 -w -Ilib t/instantiate.t
1..2
Could not load class (File::ChangeNotify::Watcher::Inotify) because : Attempt to reload File/ChangeNotify/Watcher/Inotify.pm aborted.
Compilation failed in require at /opt/local/lib/perl5/site_perl/5.10.1/darwin-thread-multi-2level/Class/MOP.pm line 129.
at /opt/local/lib/perl5/site_perl/5.10.1/darwin-thread-multi-2level/Class/MOP.pm line 114
Class::MOP::load_first_existing_class('File::ChangeNotify::Watcher::Inotify') called at /opt/local/lib/perl5/site_perl/5.10.1/darwin-thread-multi-2level/Class/MOP.pm line 135
Class::MOP::load_class('File::ChangeNotify::Watcher::Inotify') called at lib/File/ChangeNotify.pm line 34
eval {...} called at lib/File/ChangeNotify.pm line 34
File::ChangeNotify::_try_load('File::ChangeNotify::Watcher::Inotify') called at lib/File/ChangeNotify.pm line 16
File::ChangeNotify::instantiate_watcher('File::ChangeNotify', 'directories', 'ARRAY(0x100803d38)') called at t/instantiate.t line 6
---
lib/File/ChangeNotify.pm | 10 +++++++---
t/instantiate.t | 16 ++++++++++++++++
2 files changed, 23 insertions(+), 3 deletions(-)
create mode 100644 t/instantiate.t
diff --git a/lib/File/ChangeNotify.pm b/lib/File/ChangeNotify.pm
index e408d43..298a34d 100644
--- a/lib/File/ChangeNotify.pm
+++ b/lib/File/ChangeNotify.pm
@@ -3,16 +3,18 @@ package File::ChangeNotify;
use strict;
use warnings;
-our $VERSION = '0.09';
+our $VERSION = '0.10';
use Carp qw( confess );
use Class::MOP;
use Module::Pluggable::Object;
+my @usable_classes = ();
+
sub instantiate_watcher {
my $class = shift;
- for my $class ( $class->_all_classes() ) {
+ for my $class ( $class->usable_classes() ) {
if ( _try_load($class) ) {
return $class->new(@_);
}
@@ -25,9 +27,11 @@ sub instantiate_watcher {
sub usable_classes {
my $class = shift;
- return grep { _try_load($_) } $class->_all_classes();
+ return @usable_classes if @usable_classes;
+ return @usable_classes = grep { _try_load($_) } $class->_all_classes();
}
+
sub _try_load {
my $class = shift;
diff --git a/t/instantiate.t b/t/instantiate.t
new file mode 100644
index 0000000..15657cb
--- /dev/null
+++ b/t/instantiate.t
@@ -0,0 +1,16 @@
+use Test::More tests => 2;
+use File::ChangeNotify;
+
+my $watcher1 =
+ File::ChangeNotify->instantiate_watcher( directories => [qw(t)], );
+my $watcher2 =
+ File::ChangeNotify->instantiate_watcher( directories => [qw(t)], );
+
+ok(
+ $watcher1->isa('File::ChangeNotify::Watcher'),
+ 'first isa File::ChangeNotify::Watcher'
+);
+ok(
+ $watcher2->isa('File::ChangeNotify::Watcher'),
+ 'second isa File::ChangeNotify::Watcher'
+);
--
1.6.4.4