X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMouse.pm;h=58637af019e2092769e88b09d62bedcb8beb4e71;hb=9694b71b9fb63978f813900224f556ad62da729f;hp=dae207d7c9a7e68aa591a82c92d66912f23df771;hpb=306290e864ac23e5f1692c8495b0c173081a1ebb;p=gitmo%2FMouse.git diff --git a/lib/Mouse.pm b/lib/Mouse.pm index dae207d..58637af 100644 --- a/lib/Mouse.pm +++ b/lib/Mouse.pm @@ -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; } @@ -190,6 +213,12 @@ This will load a given C (or die if it's not loadable). This function can be used in place of tricks like C or using C. +=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<< >>