X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMouse.pm;h=58637af019e2092769e88b09d62bedcb8beb4e71;hb=9694b71b9fb63978f813900224f556ad62da729f;hp=1c06330de2525178b9a7e4c0609f9c13b9a3198d;hpb=c3398f5bd45f2851b7cd40ca9823bcf7d2378469;p=gitmo%2FMouse.git diff --git a/lib/Mouse.pm b/lib/Mouse.pm index 1c06330..58637af 100644 --- a/lib/Mouse.pm +++ b/lib/Mouse.pm @@ -9,16 +9,17 @@ 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; do { my $CALLER; my %exports = ( meta => sub { - my $meta = Mouse::Class->initialize($CALLER); + my $meta = Mouse::Meta::Class->initialize($CALLER); return sub { $meta }; }, @@ -36,17 +37,17 @@ do { $names = [$names] if !ref($names); for my $name (@$names) { - Mouse::Attribute->create($package, $name, @_); + Mouse::Meta::Attribute->create($package, $name, @_); } }; }, confess => sub { - return \&Carp::confess; + return \&confess; }, blessed => sub { - return \&Scalar::Util::blessed; + return \&blessed; }, ); @@ -61,8 +62,9 @@ do { strict->import; warnings->import; - no strict 'refs'; - @{ $CALLER . '::ISA' } = 'Mouse::Object'; + my $meta = Mouse::Meta::Class->initialize($CALLER); + $meta->superclasses('Mouse::Object') + unless $meta->superclasses; goto $exporter; } @@ -81,23 +83,58 @@ 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; eval { CORE::require($file) }; - confess "Could not load class ($class) because : $@" - if $@ - && $@ !~ /^Can't locate .*? at /; + confess "Could not load class ($class) because : $@" if $@; return 1; } +sub is_class_loaded { + my $class = shift; + + 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; +} + 1; __END__ =head1 NAME -Mouse - miniature Moose near the speed of light +Mouse - Moose minus antlers =head1 VERSION @@ -106,18 +143,28 @@ Version 0.01 released ??? =head1 SYNOPSIS package Point; + use Mouse; # automatically turns on strict and warnings + + has 'x' => (is => 'rw', isa => 'Int'); + has 'y' => (is => 'rw', isa => 'Int'); + + sub clear { + my $self = shift; + $self->x(0); + $self->y(0); + } + + package Point3D; use Mouse; - has x => ( - is => 'rw', - ); + extends 'Point'; - has y => ( - is => 'rw', - default => 0, - predicate => 'has_y', - clearer => 'clear_y', - ); + has 'z' => (is => 'rw', isa => 'Int'); + + #after 'clear' => sub { + # my $self = shift; + # $self->z(0); + #}; =head1 DESCRIPTION @@ -125,7 +172,7 @@ Moose. =head1 INTERFACE -=head2 meta -> Mouse::Class +=head2 meta -> Mouse::Meta::Class Returns this class' metaclass instance. @@ -150,7 +197,7 @@ L for your convenience. =head2 import -Importing Mouse will set your class' superclass list to L. +Importing Mouse will default your class' superclass list to L. You may use L to replace the superclass list. =head2 unimport @@ -162,10 +209,16 @@ L) it will break loudly instead breaking subtly. =head2 load_class Class::Name -This will load a given Class::Name> (or die if it's not loadable). +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<< >>