Catalyst::Utils::ensure_class_loaded
Yuval Kogman [Wed, 7 Jun 2006 14:23:31 +0000 (14:23 +0000)]
lib/Catalyst/Utils.pm
t/unit_utils_load_class.t [new file with mode: 0644]

index 3a0974b..ed40b02 100644 (file)
@@ -6,6 +6,7 @@ use File::Spec;
 use HTTP::Request;
 use Path::Class;
 use URI;
+use Class::Inspector;
 
 =head1 NAME
 
@@ -210,9 +211,32 @@ sub request {
     return $request;
 }
 
+=head2 ensure_class_loaded($class_name)
+
+Loads the class unless it already has been loaded.
+
+=cut
+
+sub ensure_class_loaded {
+    my $class = shift;
+
+    return if Class::Inspector->loaded( $class ); # if a symbol entry exists we don't load again
+
+    # this hack is so we don't overwrite $@ if the load did not generate an error
+    my $error;
+    {
+        local $@;
+        eval "require $class";
+        $error = $@;
+    }
+    die $error if $error;
+}
+
+
 =head1 AUTHOR
 
 Sebastian Riedel, C<sri@cpan.org>
+Yuval Kogman, C<nothingmuch@woobling.org>
 
 =head1 COPYRIGHT
 
diff --git a/t/unit_utils_load_class.t b/t/unit_utils_load_class.t
new file mode 100644 (file)
index 0000000..cddc400
--- /dev/null
@@ -0,0 +1,51 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More tests => 12;
+
+use lib "t/lib";
+
+BEGIN { use_ok("Catalyst::Utils") };
+
+{
+    package This::Module::Is::Not::In::Inc::But::Does::Exist;
+    sub moose {};
+}
+
+my $warnings = 0;
+$SIG{__WARN__} = sub { $warnings++ };
+
+ok( !Class::Inspector->loaded("TestApp::View::Dump"), "component not yet loaded" );
+
+Catalyst::Utils::ensure_class_loaded("TestApp::View::Dump");
+
+ok( Class::Inspector->loaded("TestApp::View::Dump"), "loaded ok" );
+is( $warnings, 0, "no warnings emitted" );
+
+$warnings = 0;
+
+Catalyst::Utils::ensure_class_loaded("TestApp::View::Dump");
+is( $warnings, 0, "calling again doesn't reaload" );
+
+ok( !Class::Inspector->loaded("TestApp::View::Dump::Request"), "component not yet loaded" );
+
+Catalyst::Utils::ensure_class_loaded("TestApp::View::Dump::Request");
+ok( Class::Inspector->loaded("TestApp::View::Dump::Request"), "loaded ok" );
+
+is( $warnings, 0, "calling again doesn't reaload" );
+
+undef $@;
+eval { Catalyst::Utils::ensure_class_loaded("This::Module::Is::Probably::Not::There") };
+ok( $@, "doesn't defatalize" );
+like( $@, qr/There\.pm.*\@INC/, "error looks right" );
+
+$@ = "foo";
+Catalyst::Utils::ensure_class_loaded("TestApp::View::Dump::Response");
+is( $@, "foo", '$@ is untouched' );
+
+undef $@;
+eval { Catalyst::Utils::ensure_class_loaded("This::Module::Is::Not::In::Inc::But::Does::Exist") };
+ok( !$@, "no error when loading non existent .pm that *does* have a symbol table entry" ); 
+