- Move validation of not inheriting from roles from Moose::extends to
Moose::Meta::Class::superclasses (doy)
+ * Moose::Util
+ - add ensure_all_roles() function to encapsulate the common "apply this
+ role unless the object already does it" pattern (hdp)
+
0.74 Tue, April 7, 2009
* Moose::Meta::Role
* Moose::Meta::Method::Destructor
find_meta
does_role
search_class_by_role
+ ensure_all_roles
apply_all_roles
get_all_init_args
get_all_attribute_values
return;
}
+# this can possibly behave in unexpected ways because the roles being composed
+# before being applied could differ from call to call; I'm not sure if or how
+# to document this possible quirk.
+sub ensure_all_roles {
+ my $applicant = shift;
+ _apply_all_roles($applicant, sub { !does_role($applicant, $_) }, @_);
+}
+
sub apply_all_roles {
my $applicant = shift;
+ _apply_all_roles($applicant, sub { 1 }, @_);
+}
+
+sub _apply_all_roles {
+ my $applicant = shift;
+ my $role_filter = shift;
unless (@_) {
require Moose;
}
}
+ @$roles = grep { local $_ = $_->[0]; $role_filter->() } @$roles;
+
+ return unless @$roles;
+
my $meta = ( blessed $applicant ? $applicant : find_meta($applicant) );
if ( scalar @$roles == 1 ) {
followed by an optional hash reference of options (C<exclude> and
C<alias>).
+=item B<ensure_all_roles($applicant, @roles)>
+
+This function is similar to L</apply_all_roles>, but only applies roles that
+C<$applicant> does not already consume.
+
=item B<get_all_attribute_values($meta, $instance)>
Returns a hash reference containing all of the C<$instance>'s
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More tests => 8;
+
+BEGIN {
+ use_ok('Moose::Util', ':all');
+}
+
+{
+ package Foo;
+ use Moose::Role;
+}
+
+{
+ package Bar;
+ use Moose::Role;
+}
+
+{
+ package Quux;
+ use Moose;
+}
+
+is_deeply(
+ Quux->meta->roles,
+ [],
+ "no roles yet",
+);
+
+Foo->meta->apply(Quux->meta);
+
+is_deeply(
+ Quux->meta->roles,
+ [ Foo->meta ],
+ "applied Foo",
+);
+
+Foo->meta->apply(Quux->meta);
+Bar->meta->apply(Quux->meta);
+is_deeply(
+ Quux->meta->roles,
+ [ Foo->meta, Foo->meta, Bar->meta ],
+ "duplicated Foo",
+);
+
+is(does_role('Quux', 'Foo'), 1, "Quux does Foo");
+is(does_role('Quux', 'Bar'), 1, "Quux does Bar");
+ensure_all_roles('Quux', qw(Foo Bar));
+is_deeply(
+ Quux->meta->roles,
+ [ Foo->meta, Foo->meta, Bar->meta ],
+ "unchanged, since all roles are already applied",
+);
+
+my $obj = Quux->new;
+ensure_all_roles($obj, qw(Foo Bar));
+is_deeply(
+ $obj->meta->roles,
+ [ Foo->meta, Foo->meta, Bar->meta ],
+ "unchanged, since all roles are already applied",
+);