package Role::Tiny;
sub _getglob { \*{$_[0]} }
+sub _getstash { \%{"$_[0]::"} }
use strict;
use warnings FATAL => 'all';
our %APPLIED_TO;
our %COMPOSED;
+# inlined from Moo::_Utils - update that first.
+
sub _load_module {
- return 1 if $_[0]->can('can');
(my $proto = $_[0]) =~ s/::/\//g;
+ return 1 if $INC{"${proto}.pm"};
+ # can't just ->can('can') because a sub-package Foo::Bar::Baz
+ # creates a 'Baz::' key in Foo::Bar's symbol table
+ return 1 if grep !/::$/, keys %{_getstash($_[0])||{}};
require "${proto}.pm";
return 1;
}
};
*{_getglob "${target}::with"} = sub {
die "Only one role supported at a time by with" if @_ > 1;
- $me->apply_role_to_package($_[0], $target);
+ $me->apply_role_to_package($target, $_[0]);
};
# grab all *non-constant* (ref eq 'SCALAR') subs present
# in the symbol table and store their refaddrs (no need to forcibly
}
sub apply_role_to_package {
- my ($me, $role, $to) = @_;
+ my ($me, $to, $role) = @_;
_load_module($role);
die "No roles supplied!" unless @roles;
- my $new_name = join('+', $superclass, my $compose_name = join '+', @roles);
+ my $new_name = join(
+ '__WITH__', $superclass, my $compose_name = join '__AND__', @roles
+ );
+
return $new_name if $COMPOSED{class}{$new_name};
foreach my $role (@roles) {
die "${role} is not a Role::Tiny" unless my $info = $INFO{$role};
}
- if ($] > 5.010) {
+ if ($] >= 5.010) {
require mro;
} else {
require MRO::Compat;
1;
-=pod
+=head1 NAME
+
+Role::Tiny - Roles. Like a nouvelle cusine portion size slice of Moose.
=head1 SYNOPSIS
If a method that the role L</requires> to be implemented is not implemented,
role application will fail loudly.
+=back
+
Unlike L<Class::C3>, where the B<last> class inherited from "wins," role
composition is the other way around, where first wins. In a more complete
system (see L<Moose>) roles are checked to see if they clash. The goal of this
=head2 apply_role_to_package
- Role::Tiny->apply_role_to_package('Some::Role', 'Some::Package');
+ Role::Tiny->apply_role_to_package('Some::Package', 'Some::Role');
Composes role with package
See L<< Class::Method::Modifiers/after method(s) => sub { ... } >> for full
documentation.
+=head1 AUTHORS
+
+See L<Moo> for authors.
+
+=head1 COPYRIGHT AND LICENSE
+
+See L<Moo> for the copyright and license.
+
+=cut