use MRO::Compat;
use Carp 'confess';
+use Class::Load 0.07 ();
use Scalar::Util 'weaken', 'isweak', 'reftype', 'blessed';
use Data::OptList;
use Try::Tiny;
# because I don't yet see a good reason to do so.
}
-sub _class_to_pmfile {
- my $class = shift;
-
- my $file = $class . '.pm';
- $file =~ s{::}{/}g;
-
- return $file;
+sub load_class {
+ goto &Class::Load::load_class;
}
sub load_first_existing_class {
- my $classes = Data::OptList::mkopt(\@_)
- or return;
-
- foreach my $class (@{ $classes }) {
- my $name = $class->[0];
- unless ( _is_valid_class_name($name) ) {
- my $display = defined($name) ? $name : 'undef';
- confess "Invalid class name ($display)";
- }
- }
-
- my $found;
- my %exceptions;
-
- for my $class (@{ $classes }) {
- my ($name, $options) = @{ $class };
-
- if ($options) {
- return $name if is_class_loaded($name, $options);
- if (is_class_loaded($name)) {
- # we already know it's loaded and too old, but we call
- # ->VERSION anyway to generate the exception for us
- $name->VERSION($options->{-version});
- }
- }
- else {
- return $name if is_class_loaded($name);
- }
-
- my $file = _class_to_pmfile($name);
- return $name if try {
- local $SIG{__DIE__};
- require $file;
- $name->VERSION($options->{-version})
- if defined $options->{-version};
- return 1;
- }
- catch {
- unless (/^Can't locate \Q$file\E in \@INC/) {
- confess "Couldn't load class ($name) because: $_";
- }
-
- return;
- };
- }
-
- if ( @{ $classes } > 1 ) {
- my @list = map { $_->[0] } @{ $classes };
- confess "Can't locate any of @list in \@INC (\@INC contains: @INC).";
- } else {
- confess "Can't locate " . _class_to_pmfile($classes->[0]->[0]) . " in \@INC (\@INC contains: @INC).";
- }
+ goto &Class::Load::load_first_existing_class;
}
-sub load_class {
- load_first_existing_class($_[0], ref $_[1] ? $_[1] : ());
-
- # This is done to avoid breaking code which checked the return value. Said
- # code is dumb. The return value was _always_ true, since it dies on
- # failure!
- return 1;
-}
-
-sub _is_valid_class_name {
- my $class = shift;
-
- return 0 if ref($class);
- return 0 unless defined($class);
- return 0 unless length($class);
-
- return 1 if $class =~ /^\w+(?:::\w+)*$/;
-
- return 0;
+sub is_class_loaded {
+ goto &Class::Load::is_class_loaded;
}
sub _definition_context {
Class::MOP::Method::Wrapped
Class::MOP::Method::Meta
+ Class::MOP::Method::Overload
/;
$_->meta->make_immutable(
This module was designed to be as unintrusive as possible. Many of its
features are accessible without B<any> change to your existing
-code. It is meant to be a compliment to your existing code and not an
+code. It is meant to be a complement to your existing code and not an
intrusion on your code base. Unlike many other B<Class::> modules,
this module B<does not> require you subclass it, or even that you
C<use> it in within your module's package.
-The only features which requires additions to your code are the
+The only features which require additions to your code are the
attribute handling and instance construction features, and these are
both completely optional features. The only reason for this is because
Perl 5's object system does not actually have these features built
class's ancestors.
Downward metaclass compatibility means that the metaclasses of a
-given class's ancestors are all either the same as (or a subclass
-of) that metaclass.
+given class's ancestors are all the same as (or a subclass of) that
+metaclass.
Here is a diagram showing a set of two classes (C<A> and C<B>) and
two metaclasses (C<Meta::A> and C<Meta::B>) which have correct
problem, and one which can only occur if you are doing deep metaclass
programming. So in other words, don't worry about it.
-Note that if you're using L<Moose> we encourage you to I<not> use
+Note that if you're using L<Moose> we encourage you to I<not> use the
L<metaclass> pragma, and instead use L<Moose::Util::MetaRole> to apply
roles to a class's metaclasses. This topic is covered at length in
various L<Moose::Cookbook> recipes.
=over 4
-=item B<Class::MOP::load_class($class_name, \%options?)>
-
-This will load the specified C<$class_name>, if it is not already
-loaded (as reported by C<is_class_loaded>). This function can be used
-in place of tricks like C<eval "use $module"> or using C<require>
-unconditionally.
-
-If the module cannot be loaded, an exception is thrown.
-
-You can pass a hash reference with options as second argument. The
-only option currently recognized is C<-version>, which will ensure
-that the loaded class has at least the required version.
-
-For historical reasons, this function explicitly returns a true value.
-
-=item B<Class::MOP::is_class_loaded($class_name, \%options?)>
-
-Returns a boolean indicating whether or not C<$class_name> has been
-loaded.
-
-This does a basic check of the symbol table to try and determine as
-best it can if the C<$class_name> is loaded, it is probably correct
-about 99% of the time, but it can be fooled into reporting false
-positives. In particular, loading any of the core L<IO> modules will
-cause most of the rest of the core L<IO> modules to falsely report
-having been loaded, due to the way the base L<IO> module works.
-
-You can pass a hash reference with options as second argument. The
-only option currently recognized is C<-version>, which will ensure
-that the loaded class has at least the required version.
-
=item B<Class::MOP::get_code_info($code)>
This function returns two values, the name of the package the C<$code>
=head2 Metaclass cache functions
-Class::MOP holds a cache of metaclasses. The following are functions
+C<Class::MOP> holds a cache of metaclasses. The following are functions
(B<not methods>) which can be used to access that cache. It is not
recommended that you mess with these. Bad things could happen, but if
you are brave and willing to risk it: go for it!
=back
+Some utility functions (such as C<Class::MOP::load_class>) that were
+previously defined in C<Class::MOP> regarding loading of classes have been
+extracted to L<Class::Load>. Please see L<Class::Load> for documentation.
+
=head1 SEE ALSO
=head2 Books
and offers an excellent introduction section which delves into the topic of
metaclass compatibility.
-L<http://www.iam.unibe.ch/~scg/Archive/Papers/Duca05ySafeMetaclassTrait.pdf>
+L<http://scg.unibe.ch/archive/papers/Duca05ySafeMetaclassTrait.pdf>
=item "Safe Metaclass Programming"