Some errors for auto_deref
[gitmo/Mouse.git] / lib / Mouse.pm
index 2dad7f7..58637af 100644 (file)
@@ -9,8 +9,8 @@ use Sub::Exporter;
 use Carp 'confess';
 use Scalar::Util 'blessed';
 
-use Mouse::Attribute;
-use Mouse::Class;
+use Mouse::Meta::Attribute;
+use Mouse::Meta::Class;
 use Mouse::Object;
 use Mouse::TypeRegistry;
 
@@ -19,7 +19,7 @@ do {
 
     my %exports = (
         meta => sub {
-            my $meta = Mouse::Class->initialize($CALLER);
+            my $meta = Mouse::Meta::Class->initialize($CALLER);
             return sub { $meta };
         },
 
@@ -37,7 +37,7 @@ do {
                 $names = [$names] if !ref($names);
 
                 for my $name (@$names) {
-                    Mouse::Attribute->create($package, $name, @_);
+                    Mouse::Meta::Attribute->create($package, $name, @_);
                 }
             };
         },
@@ -62,7 +62,7 @@ do {
         strict->import;
         warnings->import;
 
-        my $meta = Mouse::Class->initialize($CALLER);
+        my $meta = Mouse::Meta::Class->initialize($CALLER);
         $meta->superclasses('Mouse::Object')
             unless $meta->superclasses;
 
@@ -83,6 +83,11 @@ do {
 sub load_class {
     my $class = shift;
 
+    if (ref($class) || !defined($class) || !length($class)) {
+        my $display = defined($class) ? $class : 'undef';
+        confess "Invalid class name ($display)";
+    }
+
     return 1 if is_class_loaded($class);
 
     (my $file = "$class.pm") =~ s{::}{/}g;
@@ -96,12 +101,30 @@ sub load_class {
 sub is_class_loaded {
     my $class = shift;
 
-    no strict 'refs';
-    return 1 if defined ${"${class}::VERSION"} || defined @{"${class}::ISA"};
-    foreach my $symbol (keys %{"${class}::"}) {
-            next if substr($symbol, -2, 2) eq '::';
-            return 1 if defined &{"${class}::${symbol}"};
+    return 0 if ref($class) || !defined($class) || !length($class);
+
+    # walk the symbol table tree to avoid autovififying
+    # \*{${main::}{"Foo::"}} == \*main::Foo::
+
+    my $pack = \*::;
+    foreach my $part (split('::', $class)) {
+        return 0 unless exists ${$$pack}{"${part}::"};
+        $pack = \*{${$$pack}{"${part}::"}};
+    }
+
+    # check for $VERSION or @ISA
+    return 1 if exists ${$$pack}{VERSION}
+             && defined *{${$$pack}{VERSION}}{SCALAR};
+    return 1 if exists ${$$pack}{ISA}
+             && defined *{${$$pack}{ISA}}{ARRAY};
+
+    # check for any method
+    foreach ( keys %{$$pack} ) {
+        next if substr($_, -2, 2) eq '::';
+        return 1 if defined *{${$$pack}{$_}}{CODE};
     }
+
+    # fail
     return 0;
 }
 
@@ -149,7 +172,7 @@ Moose.
 
 =head1 INTERFACE
 
-=head2 meta -> Mouse::Class
+=head2 meta -> Mouse::Meta::Class
 
 Returns this class' metaclass instance.
 
@@ -190,6 +213,12 @@ This will load a given C<Class::Name> (or die if it's not loadable).
 This function can be used in place of tricks like
 C<eval "use $module"> or using C<require>.
 
+=head2 is_class_loaded Class::Name -> Bool
+
+Returns whether this class is actually loaded or not. It uses a heuristic which
+involves checking for the existence of C<$VERSION>, C<@ISA>, and any
+locally-defined method.
+
 =head1 AUTHOR
 
 Shawn M Moore, C<< <sartak at gmail.com> >>