use strict;
use warnings FATAL => 'all';
-our $VERSION = '1.003002';
+our $VERSION = '1.003003';
$VERSION = eval $VERSION;
our %INFO;
our %APPLIED_TO;
our %COMPOSED;
our %COMPOSITE_INFO;
+our @ON_ROLE_CREATE;
# Module state workaround totally stolen from Zefram's Module::Runtime.
BEGIN {
*_WORK_AROUND_BROKEN_MODULE_STATE = "$]" < 5.009 ? sub(){1} : sub(){0};
+ *_MRO_MODULE = "$]" < 5.010 ? sub(){"MRO/Compat.pm"} : sub(){"mro.pm"};
}
sub Role::Tiny::__GUARD__::DESTROY {
@{$INFO{$target}{not_methods}={}}{@not_methods} = @not_methods;
# a role does itself
$APPLIED_TO{$target} = { $target => undef };
+ $_->($target) for @ON_ROLE_CREATE;
}
sub role_application_steps {
my ($me, $object, @roles) = @_;
die "No roles supplied!" unless @roles;
my $class = ref($object);
- bless($object, $me->create_class_with_roles($class, @roles));
- $object;
+ # on perl < 5.8.9, magic isn't copied to all ref copies. bless the parameter
+ # directly, so at least the variable passed to us will get any magic applied
+ bless($_[1], $me->create_class_with_roles($class, @roles));
}
my $role_suffix = 'A000';
die "${role} is not a Role::Tiny" unless $me->is_role($role);
}
- if ($] >= 5.010) {
- require mro;
- } else {
- require MRO::Compat;
- }
+ require(_MRO_MODULE);
my $composite_info = $me->_composite_info_for(@roles);
my %conflicts = %{$composite_info->{conflicts}};
if (keys %conflicts) {
- my $fail =
+ my $fail =
join "\n",
map {
"Method name conflict for '$_' between roles "
delete @conflicts{@have};
if (keys %conflicts) {
- my $fail =
+ my $fail =
join "\n",
map {
"Due to a method name conflict between roles "
*$glob = $methods->{$i};
# overloads using method names have the method stored in the scalar slot
+ # and &overload::nil in the code slot.
next
unless $i =~ /^\(/
&& defined &overload::nil
Role::Tiny::does_role($proto, $role) or $proto->$existing($role);
};
no warnings 'redefine';
- *{_getglob "${to}::DOES"} = $new_sub;
+ return *{_getglob "${to}::DOES"} = $new_sub;
}
sub does_role {
my ($proto, $role) = @_;
- if ($] >= 5.010) {
- require mro;
- } else {
- require MRO::Compat;
- }
+ require(_MRO_MODULE);
foreach my $class (@{mro::get_linear_isa(ref($proto)||$proto)}) {
return 1 if exists $APPLIED_TO{$class}{$role};
}
}
1;
+__END__
=encoding utf-8
Composes another role into the current role (or class via L<Role::Tiny::With>).
If you have conflicts and want to resolve them in favour of Some::Role1 you
-can instead write:
+can instead write:
with 'Some::Role1';
with 'Some::Role2';
Returns true if the given package is a role.
+=head1 CAVEATS
+
+=over 4
+
+=item * On perl 5.8.8 and earlier, applying a role to an object won't apply any
+overloads from the role to all copies of the object.
+
+=back
+
=head1 SEE ALSO
L<Role::Tiny> is the attribute-less subset of L<Moo::Role>; L<Moo::Role> is
a meta-protocol-less subset of the king of role systems, L<Moose::Role>.
-If you don't want method modifiers and do want to be forcibly restricted
-to a single role application per class, Ovid's L<Role::Basic> exists. But
-Stevan Little (the L<Moose> author) and I don't find the additional
-restrictions to be amazingly helpful in most cases; L<Role::Basic>'s choices
-are more a guide to what you should prefer doing, to our mind, rather than
-something that needs to be enforced.
+Ovid's L<Role::Basic> provides roles with a similar scope, but without method
+modifiers, and having some extra usage restrictions.
=head1 AUTHOR