added role_type on Mouse::TypeRegistry
大沢 和宏 [Wed, 3 Dec 2008 04:11:36 +0000 (04:11 +0000)]
lib/Mouse/Meta/Class.pm
lib/Mouse/Meta/Role.pm
lib/Mouse/TypeRegistry.pm
t/800_shikabased/005-class_type.t [copied from t/800_shikabased/004-class_type.t with 100% similarity]
t/800_shikabased/006-role_type.t [moved from t/800_shikabased/004-class_type.t with 58% similarity]

index 3808291..3f9c54c 100644 (file)
@@ -37,6 +37,7 @@ sub new {
         no strict 'refs';
         \@{ $args{name} . '::ISA' };
     };
+    $args{roles} ||= [];
 
     bless \%args, $class;
 }
@@ -187,6 +188,18 @@ sub add_after_method_modifier {
     );
 }
 
+sub roles { $_[0]->{roles} }
+
+sub does_role {
+    my ($self, $role_name) = @_;
+    (defined $role_name)
+        || confess "You must supply a role name to look for";
+    for my $role (@{ $self->{roles} }) {
+        return 1 if $role->name eq $role_name;
+    }
+    return 0;
+}
+
 1;
 
 __END__
index 0e1d667..c96d822 100644 (file)
@@ -30,6 +30,7 @@ sub new {
 
     $args{attributes}       ||= {};
     $args{required_methods} ||= [];
+    $args{roles}            ||= [];
 
     bless \%args, $class;
 }
@@ -123,6 +124,9 @@ sub apply {
             }
         }
     }
+
+    # append roles
+    push @{ $class->roles }, $self, @{ $self->roles };
 }
 
 for my $modifier_type (qw/before after around/) {
@@ -140,5 +144,7 @@ for my $modifier_type (qw/before after around/) {
     };
 }
 
+sub roles { $_[0]->{roles} }
+
 1;
 
index ff2350f..15d3479 100644 (file)
@@ -25,7 +25,7 @@ sub import {
     *{"$caller\::subtype"}     = \&_subtype;
     *{"$caller\::coerce"}      = \&_coerce;
     *{"$caller\::class_type"}  = \&_class_type;
-#    *{"$caller\::role_type"}   = \&_role_type;
+    *{"$caller\::role_type"}   = \&_role_type;
 }
 
 sub _import {
@@ -62,6 +62,17 @@ sub _class_type {
     };
 }
 
+sub _role_type {
+    my $pkg = caller(0);
+    $SUBTYPE->{$pkg} ||= +{};
+    my($name, $conf) = @_;
+    my $role = $conf->{role};
+    $SUBTYPE->{$pkg}->{$name} = sub {
+        return unless defined $_ && ref($_) && $_->isa('Mouse::Object');
+        $_->meta->does_role($role);
+    };
+}
+
 sub typecast_constraints {
     my($class, $pkg, $type, $value) = @_;
     return $value unless defined $COERCE->{$pkg} && defined $COERCE->{$pkg}->{$type};
similarity index 58%
rename from t/800_shikabased/004-class_type.t
rename to t/800_shikabased/006-role_type.t
index b47077c..24165c1 100644 (file)
@@ -1,19 +1,37 @@
 use strict;
 use warnings;
-use Test::More tests => 4;
+use Test::More tests => 5;
 
 {
-    package Response::Headers;
+    package Request::Headers::Role;
+    use Mouse::Role;
+    has 'foo' => ( is => 'rw' );
+}
+
+{
+    package Request::Headers;
     use Mouse;
+    with 'Request::Headers::Role';
+}
+
+{
+    package Response::Headers::Role;
+    use Mouse::Role;
     has 'foo' => ( is => 'rw' );
 }
 
 {
+    package Response::Headers;
+    use Mouse;
+    with 'Response::Headers::Role';
+}
+
+{
     package Response;
     use Mouse;
     use Mouse::TypeRegistry;
 
-    class_type Headers => { class => 'Response::Headers' };
+    role_type Headers => { role => 'Response::Headers::Role' };
     coerce 'Headers' => +{
         HashRef => sub {
             Response::Headers->new(%{ $_ });
@@ -33,3 +51,8 @@ is($res->headers->foo, 'bar');
 $res->headers({foo => 'yay'});
 isa_ok($res->headers, 'Response::Headers');
 is($res->headers->foo, 'yay');
+
+eval {
+    $res->headers( Request::Headers->new( foo => 'baz' ) );
+};
+ok $@;