Add composition_class_roles to Meta::Class and build the Role::Composite using that.
Florian Ragwitz [Thu, 30 Jul 2009 12:18:03 +0000 (14:18 +0200)]
lib/Moose/Meta/Role.pm
lib/Moose/Meta/Role/Composite.pm

index f3363bf..8e5ef62 100644 (file)
@@ -160,6 +160,12 @@ $META->add_attribute(
     default => 'Moose::Meta::Role::Application::ToInstance',
 );
 
+$META->add_attribute(
+    'composition_class_roles',
+    reader    => 'composition_class_roles',
+    predicate => 'has_composition_class_roles',
+);
+
 ## some things don't always fit, so they go here ...
 
 sub add_attribute {
index c7329d4..4c6b13e 100644 (file)
@@ -38,6 +38,7 @@ __PACKAGE__->meta->add_attribute(
 
 sub new {
     my ($class, %params) = @_;
+
     # the roles param is required ...
     foreach ( @{$params{roles}} ) {
         unless ( $_->isa('Moose::Meta::Role') ) {
@@ -45,6 +46,23 @@ sub new {
             Moose->throw_error("The list of roles must be instances of Moose::Meta::Role, not $_");
         }
     }
+
+    my @composition_roles = map {
+        $_->has_composition_class_roles
+            ? @{ $_->composition_class_roles }
+            : ()
+    } @{ $params{roles} };
+
+    if (@composition_roles) {
+        my $meta = Moose::Meta::Class->create_anon_class(
+            superclasses => [ $class ],
+            roles        => [ @composition_roles ],
+            cache        => 1,
+        );
+        $meta->add_method(meta => sub { $meta });
+        $class = $meta->name;
+    }
+
     # and the name is created from the
     # roles if one has not been provided
     $params{name} ||= (join "|" => map { $_->name } @{$params{roles}});