Skip Menu |

This queue is for tickets about the File-ChangeNotify CPAN distribution.

Report information
The Basics
Id: 52477
Status: resolved
Priority: 0/
Queue: File-ChangeNotify

People
Owner: Nobody in particular
Requestors: mgrimes [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: (no value)
Fixed in: 0.10



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