use strict;
use warnings FATAL => 'all';
-our $VERSION = '1.003002'; # 1.3.2
+our $VERSION = '1.003002';
$VERSION = eval $VERSION;
our %INFO;
my $me = shift;
strict->import;
warnings->import(FATAL => 'all');
- return if $INFO{$target}; # already exported into this package
+ return if $me->is_role($target); # already exported into this package
$INFO{$target}{is_role} = 1;
# get symbol table reference
my $stash = _getstash($target);
_load_module($role);
die "This is apply_role_to_package" if ref($to);
- die "${role} is not a Role::Tiny" unless $INFO{$role};
+ die "${role} is not a Role::Tiny" unless $me->is_role($role);
foreach my $step ($me->role_application_steps) {
$me->$step($to, $role);
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';
foreach my $role (@roles) {
_load_module($role);
- die "${role} is not a Role::Tiny" unless $INFO{$role};
+ die "${role} is not a Role::Tiny" unless $me->is_role($role);
}
if ($] >= 5.010) {
sub methods_provided_by {
my ($me, $role) = @_;
- die "${role} is not a Role::Tiny" unless my $info = $INFO{$role};
- (keys %{$me->_concrete_methods_of($role)}, @{$info->{requires}||[]});
+ die "${role} is not a Role::Tiny" unless $me->is_role($role);
+ (keys %{$me->_concrete_methods_of($role)}, @{$INFO{$role}->{requires}||[]});
}
sub _install_methods {
foreach my $i (grep !exists $has_methods{$_}, keys %$methods) {
no warnings 'once';
- *{_getglob "${to}::${i}"} = $methods->{$i};
+ my $glob = _getglob "${to}::${i}";
+ *$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
+ && $methods->{$i} == \&overload::nil;
+
+ my $overload = ${ *{_getglob "${role}::${i}"}{SCALAR} };
+ next
+ unless defined $overload;
+
+ *$glob = \$overload;
}
-
+
$me->_install_does($to);
}
my $FALLBACK = sub { 0 };
sub _install_does {
my ($me, $to) = @_;
-
+
# only add does() method to classes
- return if $INFO{$to};
-
+ return if $me->is_role($to);
+
# add does() only if they don't have one
*{_getglob "${to}::does"} = \&does_role unless $to->can('does');
-
- return if ($to->can('DOES') and $to->can('DOES') != (UNIVERSAL->can('DOES') || 0));
-
+
+ return
+ if $to->can('DOES') and $to->can('DOES') != (UNIVERSAL->can('DOES') || 0);
+
my $existing = $to->can('DOES') || $to->can('isa') || $FALLBACK;
my $new_sub = sub {
my ($proto, $role) = @_;
a dependency. If your L<Role::Tiny> role uses modifiers you must depend on
both L<Class::Method::Modifiers> and L<Role::Tiny>.
+=head2 Strict and Warnings
+
+In addition to importing subroutines, using C<Role::Tiny> applies L<strict> and
+L<fatal warnings|perllexwarn/Fatal Warnings> to the caller. It's possible to
+disable these if desired:
+
+ use Role::Tiny;
+ use warnings NONFATAL => 'all';
+
=head1 SUBROUTINES
=head2 does_role
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.
+
=head1 SEE ALSO
L<Role::Tiny> is the attribute-less subset of L<Moo::Role>; L<Moo::Role> is
tobyink - Toby Inkster (cpan:TOBYINK) <tobyink@cpan.org>
+haarg - Graham Knop (cpan:HAARG) <haarg@haarg.org>
+
=head1 COPYRIGHT
Copyright (c) 2010-2012 the Role::Tiny L</AUTHOR> and L</CONTRIBUTORS>