better diagnostics when bad parameters given to has
[gitmo/Moo.git] / lib / Moo / Role.pm
index c890dfe..596f19b 100644 (file)
@@ -29,10 +29,16 @@ sub import {
   # get symbol table reference
   my $stash = do { no strict 'refs'; \%{"${target}::"} };
   _install_tracked $target => has => sub {
-    my ($name_proto, %spec) = @_;
-    my $name_isref = ref $name_proto eq 'ARRAY';
-    foreach my $name ($name_isref ? @$name_proto : $name_proto) {
-      my $spec_ref = $name_isref ? +{%spec} : \%spec;
+    my $name_proto = shift;
+    my @name_proto = ref $name_proto eq 'ARRAY' ? @$name_proto : $name_proto;
+    if (@_ % 2 != 0) {
+      require Carp;
+      Carp::croak("Invalid options for " . join(', ', map "'$_'", @name_proto)
+        . " attribute(s): even number of arguments expected, got " . scalar @_)
+    }
+    my %spec = @_;
+    foreach my $name (@name_proto) {
+      my $spec_ref = @name_proto > 1 ? +{%spec} : \%spec;
       ($INFO{$target}{accessor_maker} ||= do {
         require Method::Generate::Accessor;
         Method::Generate::Accessor->new
@@ -168,6 +174,7 @@ sub _inhale_if_moose {
     }
     require Class::Method::Modifiers if @$mods;
     $INFO{$role}{inhaled_from_moose} = 1;
+    $INFO{$role}{is_role} = 1;
   }
 }
 
@@ -206,10 +213,16 @@ sub _make_accessors {
   }
 }
 
+sub role_application_steps {
+  qw(_handle_constructor _maybe_make_accessors),
+    $_[0]->SUPER::role_application_steps;
+}
+
 sub apply_roles_to_package {
   my ($me, $to, @roles) = @_;
   foreach my $role (@roles) {
-      $me->_inhale_if_moose($role);
+    $me->_inhale_if_moose($role);
+    die "${role} is not a Moo::Role" unless $INFO{$role};
   }
   $me->SUPER::apply_roles_to_package($to, @roles);
 }
@@ -217,9 +230,7 @@ sub apply_roles_to_package {
 sub apply_single_role_to_package {
   my ($me, $to, $role) = @_;
   $me->_inhale_if_moose($role);
-  die "${role} is not a Moo::Role" unless my $info = $INFO{$role};
-  $me->_handle_constructor($to, $role);
-  $me->_maybe_make_accessors($to, $role);
+  die "${role} is not a Moo::Role" unless $INFO{$role};
   $me->SUPER::apply_single_role_to_package($to, $role);
 }
 
@@ -254,7 +265,7 @@ sub create_class_with_roles {
     die "${role} is not a Role::Tiny" unless $INFO{$role};
   }
 
-  $Moo::MAKERS{$new_name} = {};
+  $Moo::MAKERS{$new_name} = {is_class => 1};
 
   $me->_handle_constructor($new_name, $_) for @roles;