=head1 NAME
-Class::C3::Componentised
-
-=head1 DESCRIPTION
-
-Load mix-ins or components to your C3-based class.
+Class::C3::Componentised - Load mix-ins or components to your C3-based class
=head1 SYNOPSIS
package main;
- MyModule->load_components( qw/Foo Bar/ );
+ MyModule->load_components( qw/Foo Bar/ );
# Will load MyModule::Component::Foo and MyModule::Component::Bar
=head1 DESCRIPTION
This will inject base classes to your module using the L<Class::C3> method
resolution order.
-Please note: these are not plugins that can take precedence over methods
+Please note: these are not plugins that can take precedence over methods
declared in MyModule. If you want something like that, consider
L<MooseX::Object::Pluggable>.
# Therefore leaving it in indefinitely.
use MRO::Compat;
-use Carp;
+use Carp ();
+use List::Util ();
-our $VERSION = 1.0006;
+our $VERSION = '1.001002';
+$VERSION =~ tr/_//d;
my $invalid_class = qr/(?: \b:\b | \:{3,} | \:\:$ )/x;
=head2 load_components( @comps )
-Loads the given components into the current module. If a module begins with a
+Loads the given components into the current module. If a module begins with a
C<+> character, it is taken to be a fully qualified class name, otherwise
C<< $class->component_base_class >> is prepended to it.
=head2 load_own_components( @comps )
-Similar to L<load_components>, but assumes every class is C<"$class::$comp">.
+Similar to L<load_components|/load_components( @comps )>, but assumes every
+class is C<"$class::$comp">.
=cut
=head2 load_optional_components
-As L<load_components>, but will silently ignore any components that cannot be
-found.
+As L<load_components|/load_components( @comps )>, but will silently ignore any
+components that cannot be found.
=cut
return if ( *{"${f_class}::$_"}{CODE} );
}
-
# require always returns true on success
- eval { require($file) } or do {
+ # ill-behaved modules might very well obliterate $_
+ eval { local $_; require($file) } or do {
$@ = "Invalid class name '$f_class'" if $f_class =~ $invalid_class;
if ($class->can('throw_exception')) {
$class->throw_exception($@);
} else {
- croak $@;
+ Carp::croak $@;
}
};
Returns true if the specified class is installed or already loaded, false
otherwise.
-Note that the underlying mechanism (Class::Inspector->installed()) used by this
-sub will not, at the time of writing, correctly function when @INC includes
-coderefs. Since PAR relies upon coderefs in @INC, this function should be
-avoided in modules that are likely to be included within a PAR.
-
=cut
sub ensure_class_found {
=head2 inject_base
-Does the actual magic of adjusting @ISA on the target module.
+Does the actual magic of adjusting C<@ISA> on the target module.
=cut
my $class = shift;
my $target = shift;
- my %isa = map { $_ => 1 } ($target, @{mro::get_linear_isa($target)} );
+ mro::set_mro($target, 'c3');
- for (reverse @_) {
- no strict 'refs';
- unless ($isa{$_}++) {
- unshift ( @{"${target}::ISA"}, $_ );
+ for my $comp (reverse @_) {
+ my $apply = do {
+ no strict 'refs';
+ sub { unshift ( @{"${target}::ISA"}, $comp ) };
+ };
+ unless ($target eq $comp || $target->isa($comp)) {
+ our %APPLICATOR_FOR;
+ if (my $apply_class
+ = List::Util::first { $APPLICATOR_FOR{$_} } @{mro::get_linear_isa($comp)}
+ ) {
+ $APPLICATOR_FOR{$apply_class}->_apply_component_to_class($comp,$target,$apply);
+ } else {
+ $apply->();
+ }
}
}
-
- mro::set_mro($target, 'c3');
}
=head2 load_optional_class
}
}
-=head1 AUTHOR
+=head1 AUTHORS
+
+Matt S. Trout and the L<DBIx::Class team|DBIx::Class/CONTRIBUTORS>
+
+Pulled out into separate module by Ash Berlin C<< <ash@cpan.org> >>
+
+Optimizations and overall bolt-tightening by Peter "ribasushi" Rabbitson
+C<< <ribasushi@cpan.org> >>
-Matt S. Trout and the DBIx::Class team
+=head1 COPYRIGHT
-Pulled out into seperate module by Ash Berlin C<< <ash@cpan.org> >>
+Copyright (c) 2006 - 2011 the Class::C3::Componentised L</AUTHORS> as listed
+above.
=head1 LICENSE