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 };
},
$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;
},
);
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;
}
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
=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
=head1 INTERFACE
-=head2 meta -> Mouse::Class
+=head2 meta -> Mouse::Meta::Class
Returns this class' metaclass instance.
=head2 import
-Importing Mouse will set your class' superclass list to L<Mouse::Object>.
+Importing Mouse will default your class' superclass list to L<Mouse::Object>.
You may use L</extends> to replace the superclass list.
=head2 unimport
=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<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> >>