X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMouse.pm;h=58637af019e2092769e88b09d62bedcb8beb4e71;hb=9694b71b9fb63978f813900224f556ad62da729f;hp=2dad7f7e0c92f08d5955f0c0251eaf61ae948b47;hpb=2a674d232b1060884cceddaa23be19aa7b335a33;p=gitmo%2FMouse.git diff --git a/lib/Mouse.pm b/lib/Mouse.pm index 2dad7f7..58637af 100644 --- a/lib/Mouse.pm +++ b/lib/Mouse.pm @@ -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 (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<< >>