From: Shawn M Moore Date: Sun, 10 May 2009 03:34:15 +0000 (-0400) Subject: Add role_for_combination for MXRP X-Git-Tag: 0.78~17 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=31d96c3e66fa1178fba263bff87ab025a344e029;p=gitmo%2FMoose.git Add role_for_combination for MXRP --- diff --git a/Changes b/Changes index 4427154..30d8367 100644 --- a/Changes +++ b/Changes @@ -28,6 +28,10 @@ for, noteworthy changes. - Fix metaclass incompatibility errors when extending a vanilla perl class which isa Moose class with a metaclass role applied (t0m) + * Moose::Meta::Role + - Add a role-combination hook, role_for_combination, for the + benefit of MooseX::Role::Parameterized (Sartak) + 0.77 Sat, May 2, 2009 * Moose::Meta::Role - Add explicit use of Devel::GlobalDestruction and Sub::Name diff --git a/lib/Moose/Meta/Role.pm b/lib/Moose/Meta/Role.pm index 65de5aa..d38ec2a 100644 --- a/lib/Moose/Meta/Role.pm +++ b/lib/Moose/Meta/Role.pm @@ -446,6 +446,11 @@ sub apply { } } +sub role_for_combination { + my ($self, $params) = @_; + return $self; +} + sub combine { my ($class, @role_specs) = @_; @@ -454,10 +459,14 @@ sub combine { my (@roles, %role_params); while (@role_specs) { - my ($role, $params) = @{ splice @role_specs, 0, 1 }; - push @roles => Class::MOP::class_of($role); + my ($role_name, $params) = @{ splice @role_specs, 0, 1 }; + my $requested_role = Class::MOP::class_of($role_name); + + my $actual_role = $requested_role->role_for_combination($params); + push @roles => $actual_role; + next unless defined $params; - $role_params{$role} = $params; + $role_params{$actual_role->name} = $params; } my $c = Moose::Meta::Role::Composite->new(roles => \@roles); @@ -744,6 +753,12 @@ and C keys to control how methods are composed from the role. The return value is a new L that represents the combined roles. +=item B<< Moose::Meta::Role->role_for_combination($options) >> + +This is a hook for incorporating role-combination parameters. This +method returns a role metaobject (by default the invocant role) to be +used for the combination. + =item B<< Moose::Meta::Role->create($name, %options) >> This method is identical to the L C diff --git a/t/030_roles/040_role_for_combination.t b/t/030_roles/040_role_for_combination.t new file mode 100644 index 0000000..302e334 --- /dev/null +++ b/t/030_roles/040_role_for_combination.t @@ -0,0 +1,45 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use Test::More tests => 3; + +my $OPTS; +do { + package My::Singleton::Role; + use Moose::Role; + + sub foo { 'My::Singleton::Role' } + + package My::Role::Metaclass; + use Moose; + BEGIN { extends 'Moose::Meta::Role' }; + + sub role_for_combination { + my ($self, $opts) = @_; + $OPTS = $opts; + return My::Singleton::Role->meta; + } + + package My::Special::Role; + use Moose::Role -metaclass => 'My::Role::Metaclass'; + + sub foo { 'My::Special::Role' } + + package My::Usual::Role; + use Moose::Role; + + sub bar { 'My::Usual::Role' } + + package My::Class; + use Moose; + + with ( + 'My::Special::Role' => { number => 1 }, + 'My::Usual::Role' => { number => 2 }, + ); +}; + +is(My::Class->foo, 'My::Singleton::Role', 'role_for_combination applied'); +is(My::Class->bar, 'My::Usual::Role', 'collateral role'); +is_deeply($OPTS, { number => 1 }); +