use Scalar::Util 'blessed';
use Class::MOP 0.60;
-our $VERSION = '0.93_02';
+our $VERSION = '1.08';
$VERSION = eval $VERSION;
our $AUTHORITY = 'cpan:STEVAN';
search_class_by_role
ensure_all_roles
apply_all_roles
+ with_traits
get_all_init_args
get_all_attribute_values
resolve_metatrait_alias
}
sub search_class_by_role {
- my ($class_or_obj, $role_name) = @_;
+ my ($class_or_obj, $role) = @_;
my $meta = find_meta($class_or_obj);
return unless defined $meta;
+ my $role_name = blessed $role ? $role->name : $role;
+
foreach my $class ($meta->class_precedence_list) {
my $_meta = find_meta($class);
my $roles = Data::OptList::mkopt( [@_] );
+ my @role_metas;
foreach my $role (@$roles) {
- Class::MOP::load_class( $role->[0] );
- my $meta = Class::MOP::class_of( $role->[0] );
+ my $meta;
+
+ if ( blessed $role->[0] ) {
+ $meta = $role->[0];
+ }
+ else {
+ Class::MOP::load_class( $role->[0] , $role->[1] );
+ $meta = Class::MOP::class_of( $role->[0] );
+ }
unless ($meta && $meta->isa('Moose::Meta::Role') ) {
require Moose;
. $role->[0]
. " is not a Moose role" );
}
+
+ push @role_metas, [ $meta, $role->[1] ];
}
if ( defined $role_filter ) {
- @$roles = grep { local $_ = $_->[0]; $role_filter->() } @$roles;
+ @role_metas = grep { local $_ = $_->[0]; $role_filter->() } @role_metas;
}
- return unless @$roles;
+ return unless @role_metas;
my $meta = ( blessed $applicant ? $applicant : find_meta($applicant) );
- if ( scalar @$roles == 1 ) {
- my ( $role, $params ) = @{ $roles->[0] };
- my $role_meta = Class::MOP::class_of($role);
- $role_meta->apply( $meta, ( defined $params ? %$params : () ) );
+ if ( scalar @role_metas == 1 ) {
+ my ( $role, $params ) = @{ $role_metas[0] };
+ $role->apply( $meta, ( defined $params ? %$params : () ) );
}
else {
- Moose::Meta::Role->combine( @$roles )->apply($meta);
+ Moose::Meta::Role->combine(@role_metas)->apply($meta);
}
}
+sub with_traits {
+ my ($class, @roles) = @_;
+ return $class unless @roles;
+ return Moose::Meta::Class->create_anon_class(
+ superclasses => [$class],
+ roles => \@roles,
+ cache => 1,
+ )->name;
+}
+
# instance deconstruction ...
sub get_all_attribute_values {
$meta->$add_modifier_method( $_->name, $code )
for @matched_methods;
}
+ elsif ($method_modifier_type eq 'ARRAY') {
+ $meta->$add_modifier_method( $_, $code ) for @{$args->[0]};
+ }
+ else {
+ $meta->throw_error(
+ sprintf(
+ "Methods passed to %s must be provided as a list, arrayref or regex, not %s",
+ $modifier_name,
+ $method_modifier_type,
+ )
+ );
+ }
}
else {
$meta->$add_modifier_method( $_, $code ) for @{$args};
metaclass for the class, if one exists. It will B<not> create one if it
does not yet exist.
-=item B<does_role($class_or_obj, $role_name)>
+=item B<does_role($class_or_obj, $role_or_obj)>
-Returns true if C<$class_or_obj> does the given C<$role_name>.
+Returns true if C<$class_or_obj> does the given C<$role_or_obj>. The role can
+be provided as a name or a L<Moose::Meta::Role> object.
-The class must already have a metaclass for this to work.
+The class must already have a metaclass for this to work. If it doesn't, this
+function simply returns false.
-=item B<search_class_by_role($class_or_obj, $role_name)>
+=item B<search_class_by_role($class_or_obj, $role_or_obj)>
Returns the first class in the class's precedence list that does
-C<$role_name>, if any.
+C<$role_or_obj>, if any. The role can be either a name or a
+L<Moose::Meta::Role> object.
The class must already have a metaclass for this to work.
The C<$applicant> must already have a metaclass object.
-The list of C<@roles> should be a list of names, each of which can be
-followed by an optional hash reference of options (C<-excludes> and
-C<-alias>).
+The list of C<@roles> should a list of names or L<Moose::Meta::Role> objects,
+each of which can be followed by an optional hash reference of options
+(C<-excludes> 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<with_traits($class_name, @role_names)>
+
+This function creates a new class from C<$class_name> with each of
+C<@role_names> applied. It returns the name of the new class.
+
=item B<get_all_attribute_values($meta, $instance)>
Returns a hash reference containing all of the C<$instance>'s
The name resolution mechanism is covered in
L<Moose/Metaclass and Trait Name Resolution>.
-=item B<english_list(@items)>
-
-Given a list of scalars, turns them into a proper list in English
-("one and two", "one, two, three, and four"). This is used to help us
-make nicer error messages.
-
=item B<meta_class_alias($to[, $from])>
=item B<meta_attribute_alias($to[, $from])>
C<$from> is unspecified), so that
L<Moose/Metaclass and Trait Name Resolution> works properly.
+=item B<english_list(@items)>
+
+Given a list of scalars, turns them into a proper list in English
+("one and two", "one, two, three, and four"). This is used to help us
+make nicer error messages.
+
=back
=head1 TODO