bump version for release
[gitmo/Role-Tiny.git] / lib / Role / Tiny.pm
index cd32786..6620964 100644 (file)
@@ -6,7 +6,7 @@ sub _getstash { \%{"$_[0]::"} }
 use strict;
 use warnings FATAL => 'all';
 
-our $VERSION = '1.001002'; # 1.1.2
+our $VERSION = '1.001005'; # 1.1.5
 $VERSION = eval $VERSION;
 
 our %INFO;
@@ -51,13 +51,16 @@ sub import {
     *{_getglob "${target}::${type}"} = sub {
       require Class::Method::Modifiers;
       push @{$INFO{$target}{modifiers}||=[]}, [ $type => @_ ];
+      return;
     };
   }
   *{_getglob "${target}::requires"} = sub {
     push @{$INFO{$target}{requires}||=[]}, @_;
+    return;
   };
   *{_getglob "${target}::with"} = sub {
     $me->apply_roles_to_package($target, @_);
+    return;
   };
   # grab all *non-constant* (stash slot is not a scalarref) subs present
   # in the symbol table and store their refaddrs (no need to forcibly
@@ -130,6 +133,18 @@ sub create_class_with_roles {
     require MRO::Compat;
   }
 
+  my %conflicts = %{$me->_composite_info_for(@roles)->{conflicts}};
+  if (keys %conflicts) {
+    my $fail = 
+      join "\n",
+        map {
+          "Method name conflict for '$_' between roles "
+          ."'".join(' and ', sort values %{$conflicts{$_}})."'"
+          .", cannot apply these simultaneously to an object."
+        } keys %conflicts;
+    die $fail;
+  }
+
   my @composable = map $me->_composable_package_for($_), reverse @roles;
 
   *{_getglob("${new_name}::ISA")} = [ @composable, $superclass ];
@@ -173,7 +188,14 @@ sub apply_roles_to_package {
         } keys %conflicts;
     die $fail;
   }
-  delete $INFO{$to}{methods}; # reset since we're about to add methods
+
+  # the if guard here is essential since otherwise we accidentally create
+  # a $INFO for something that isn't a Role::Tiny (or Moo::Role) because
+  # autovivification hates us and wants us to die()
+  if ($INFO{$to}) {
+    delete $INFO{$to}{methods}; # reset since we're about to add methods
+  }
+
   $me->apply_role_to_package($to, $_) for @roles;
   $APPLIED_TO{$to}{join('|',@roles)} = 1;
 }
@@ -237,7 +259,7 @@ sub _concrete_methods_of {
   my $stash = do { no strict 'refs'; \%{"${role}::"}};
   # reverse so our keys become the values (captured coderefs) in case
   # they got copied or re-used since
-  my $not_methods = { reverse %{$info->{not_methods}} };
+  my $not_methods = { reverse %{$info->{not_methods}||{}} };
   $info->{methods} ||= +{
     # grab all code entries that aren't in the not_methods list
     map {
@@ -295,7 +317,15 @@ sub _install_single_modifier {
 
 sub does_role {
   my ($proto, $role) = @_;
-  return exists $APPLIED_TO{ref($proto)||$proto}{$role};
+  if ($] >= 5.010) {
+    require mro;
+  } else {
+    require MRO::Compat;
+  }
+  foreach my $class (@{mro::get_linear_isa(ref($proto)||$proto)}) {
+    return 1 if exists $APPLIED_TO{$class}{$role};
+  }
+  return 0;
 }
 
 1;
@@ -507,6 +537,8 @@ perigrin - Chris Prather (cpan:PERIGRIN) <chris@prather.org>
 
 Mithaldu - Christian Walde (cpan:MITHALDU) <walde.christian@googlemail.com>
 
+ilmari - Dagfinn Ilmari MannsÃ¥ker (cpan:ILMARI) <ilmari@ilmari.org>
+
 =head1 COPYRIGHT
 
 Copyright (c) 2010-2012 the Role::Tiny L</AUTHOR> and L</CONTRIBUTORS>