Fix load_optional_class inspired by RT#56565
Peter Rabbitson [Wed, 23 Feb 2011 13:39:03 +0000 (13:39 +0000)]
Changes
lib/Class/C3/Componentised.pm
t/01-basic.t

diff --git a/Changes b/Changes
index d968c09..73ab6df 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,5 +1,8 @@
 Revision history for Class-C3-Componentised
 
+        Throw a readable exception when load_optional_class is given an
+        invalid class name
+
 1.0006   08 Sep 2009
         Allow derived classes without component_base_class(), given all
         arguments to load_components are absolute class names (+Classname)
index 5a33b39..e592fe1 100644 (file)
@@ -51,6 +51,8 @@ use Carp;
 
 our $VERSION = 1.0006;
 
+my $invalid_class = qr/(?: \b:\b | \:{3,} | \:\:$ )/x;
+
 =head2 load_components( @comps )
 
 Loads the given components into the current module. If a module begins with a 
@@ -144,8 +146,7 @@ sub ensure_class_loaded {
   # require always returns true on success
   eval { require($file) } or do {
 
-    $@ = "Invalid class name $f_class"
-      if ($f_class=~m/(?:\b:\b|\:{3,})/);
+    $@ = "Invalid class name '$f_class'" if $f_class =~ $invalid_class;
 
     if ($class->can('throw_exception')) {
       $class->throw_exception($@);
@@ -218,11 +219,15 @@ sub load_optional_class {
 
   my $err = $@;   # so we don't lose it
 
-  my $fn = quotemeta( (join ('/', split ('::', $f_class) ) ) . '.pm' );
-  if ($err =~ /Can't locate ${fn} in \@INC/ ) {
-    return 0;
+  if ($f_class =~ $invalid_class) {
+    $err = "Invalid class name '$f_class'";
+  }
+  else {
+    my $fn = quotemeta( (join ('/', split ('::', $f_class) ) ) . '.pm' );
+    return 0 if ($err =~ /Can't locate ${fn} in \@INC/ );
   }
-  elsif ($class->can('throw_exception')) {
+
+  if ($class->can('throw_exception')) {
     $class->throw_exception($err);
   }
   else {
index 12cad2f..d4603d0 100644 (file)
@@ -8,7 +8,7 @@ use Class::Inspector;
 
 use lib "$FindBin::Bin/lib";
 
-plan tests => 22;
+plan tests => 23;
 
 BEGIN {
   package TestPackage::A;
@@ -54,6 +54,9 @@ throws_ok (
   'MyModule::ErrorComponent threw ok'
 );
 
+eval { MyModule->load_optional_class('ENDS::WITH::COLONS::') };
+like( $@, qr/Invalid class name 'ENDS::WITH::COLONS::'/, 'Throw on Class::' );
+
 # Simulate a PAR environment
 { 
   my @code;