our $VERSION = '0.02';
+## the meta for the role package
+
__PACKAGE__->meta->add_attribute('role_meta' => (
- reader => 'role_meta'
+ reader => 'role_meta'
+));
+
+## roles
+
+__PACKAGE__->meta->add_attribute('roles' => (
+ reader => 'get_roles',
+ default => sub { [] }
));
+## attributes
+
__PACKAGE__->meta->add_attribute('attribute_map' => (
reader => 'get_attribute_map',
default => sub { {} }
));
-__PACKAGE__->meta->add_attribute('method_modifier_map' => (
- reader => 'get_method_modifier_map',
- default => sub {
- return {
- before => {},
- after => {},
- around => {},
- override => {}
- };
- }
+## method modifiers
+
+__PACKAGE__->meta->add_attribute('before_method_modifiers' => (
+ reader => 'get_before_method_modifiers_map',
+ default => sub { {} } # keyed by method name, then arrays of method-modifiers
));
+__PACKAGE__->meta->add_attribute('after_method_modifiers' => (
+ reader => 'get_after_method_modifiers_map',
+ default => sub { {} } # keyed by method name, then arrays of method-modifiers
+));
+
+__PACKAGE__->meta->add_attribute('around_method_modifiers' => (
+ reader => 'get_around_method_modifiers_map',
+ default => sub { {} } # keyed by method name, then arrays of method-modifiers
+));
+
+__PACKAGE__->meta->add_attribute('override_method_modifiers' => (
+ reader => 'get_override_method_modifiers_map',
+ default => sub { {} } # (<name> => CODE)
+));
+
+## methods ...
+
sub new {
my $class = shift;
my %options = @_;
- $options{role_meta} = Class::MOP::Class->initialize(
+ $options{'role_meta'} = Class::MOP::Class->initialize(
$options{role_name},
':method_metaclass' => 'Moose::Meta::Role::Method'
);
# add it, although it could be overriden
$other->add_override_method_modifier(
$method_name,
- $_,
+ $self->get_override_method_modifier($method_name),
$self->name
- ) foreach $self->get_method_modifiers('override' => $method_name);
+ );
}
foreach my $method_name ($self->get_method_modifier_list('before')) {
$other->add_before_method_modifier(
$method_name,
$_
- ) foreach $self->get_method_modifiers('before' => $method_name);
+ ) foreach $self->get_before_method_modifiers($method_name);
}
foreach my $method_name ($self->get_method_modifier_list('after')) {
$other->add_after_method_modifier(
$method_name,
$_
- ) foreach $self->get_method_modifiers('after' => $method_name);
+ ) foreach $self->get_after_method_modifiers($method_name);
}
foreach my $method_name ($self->get_method_modifier_list('around')) {
$other->add_around_method_modifier(
$method_name,
$_
- ) foreach $self->get_method_modifiers('around' => $method_name);
+ ) foreach $self->get_around_method_modifiers($method_name);
}
## add the roles and set does()
}) unless $other->has_method('does');
}
+## subroles
+
+sub add_role {
+ my ($self, $role) = @_;
+ (blessed($role) && $role->isa('Moose::Meta::Role'))
+ || confess "Roles must be instances of Moose::Meta::Role";
+ push @{$self->get_roles} => $role;
+}
+
+sub does_role {
+ my ($self, $role_name) = @_;
+ (defined $role_name)
+ || confess "You must supply a role name to look for";
+ foreach my $role (@{$self->get_roles}) {
+ return 1 if $role->name eq $role_name;
+ }
+ return 0;
+}
+
+## methods
+
# NOTE:
# we delegate to some role_meta methods for convience here
# the Moose::Meta::Role is meant to be a read-only interface
# method modifiers
-sub add_method_modifier {
+# mimic the metaclass API
+sub add_before_method_modifier { (shift)->_add_method_modifier('before', @_) }
+sub add_around_method_modifier { (shift)->_add_method_modifier('around', @_) }
+sub add_after_method_modifier { (shift)->_add_method_modifier('after', @_) }
+
+sub _add_method_modifier {
my ($self, $modifier_type, $method_name, $method) = @_;
- $self->get_method_modifier_map->{$modifier_type}->{$method_name} = []
- unless exists $self->get_method_modifier_map->{$modifier_type}->{$method_name};
- push @{$self->get_method_modifier_map->{$modifier_type}->{$method_name}} => $method;
+ my $accessor = "get_${modifier_type}_method_modifiers_map";
+ $self->$accessor->{$method_name} = []
+ unless exists $self->$accessor->{$method_name};
+ push @{$self->$accessor->{$method_name}} => $method;
}
-sub has_method_modifiers {
- my ($self, $modifier_type, $method_name) = @_;
- exists $self->get_method_modifier_map->{$modifier_type}->{$method_name} ? 1 : 0
+sub add_override_method_modifier {
+ my ($self, $method_name, $method) = @_;
+ $self->get_override_method_modifiers_map->{$method_name} = $method;
}
-sub get_method_modifiers {
+sub has_before_method_modifiers { (shift)->_has_method_modifiers('before', @_) }
+sub has_around_method_modifiers { (shift)->_has_method_modifiers('around', @_) }
+sub has_after_method_modifiers { (shift)->_has_method_modifiers('after', @_) }
+
+# override just checks for one,..
+# but we can still re-use stuff
+sub has_override_method_modifier { (shift)->_has_method_modifiers('override', @_) }
+
+sub _has_method_modifiers {
my ($self, $modifier_type, $method_name) = @_;
- @{$self->get_method_modifier_map->{$modifier_type}->{$method_name}};
+ my $accessor = "get_${modifier_type}_method_modifiers_map";
+ # NOTE:
+ # for now we assume that if it exists,..
+ # it has at least one modifier in it
+ (exists $self->$accessor->{$method_name}) ? 1 : 0;
}
-sub remove_method_modifiers {
+sub get_before_method_modifiers { (shift)->_get_method_modifiers('before', @_) }
+sub get_around_method_modifiers { (shift)->_get_method_modifiers('around', @_) }
+sub get_after_method_modifiers { (shift)->_get_method_modifiers('after', @_) }
+
+sub _get_method_modifiers {
my ($self, $modifier_type, $method_name) = @_;
- delete $self->get_method_modifier_map->{$modifier_type}->{$method_name};
+ my $accessor = "get_${modifier_type}_method_modifiers_map";
+ @{$self->$accessor->{$method_name}};
+}
+
+sub get_override_method_modifier {
+ my ($self, $method_name) = @_;
+ $self->get_override_method_modifiers_map->{$method_name};
}
sub get_method_modifier_list {
my ($self, $modifier_type) = @_;
- keys %{$self->get_method_modifier_map->{$modifier_type}};
+ my $accessor = "get_${modifier_type}_method_modifiers_map";
+ keys %{$self->$accessor};
}
package Moose::Meta::Role::Method;
=over 4
+=item B<get_roles>
+
+=item B<add_role>
+
+=item B<does_role>
+
+=back
+
+=over 4
+
=item B<get_method>
=item B<has_method>
=over 4
-=item B<add_method_modifier>
+=item B<add_after_method_modifier>
+
+=item B<add_around_method_modifier>
+
+=item B<add_before_method_modifier>
+
+=item B<add_override_method_modifier>
+
+=over 4
+
+=back
+
+=item B<has_after_method_modifiers>
+
+=item B<has_around_method_modifiers>
+
+=item B<has_before_method_modifiers>
+
+=item B<has_override_method_modifier>
+
+=over 4
+
+=back
+
+=item B<get_after_method_modifiers>
-=item B<get_method_modifiers>
+=item B<get_around_method_modifiers>
-=item B<has_method_modifiers>
+=item B<get_before_method_modifiers>
=item B<get_method_modifier_list>
-=item B<get_method_modifier_map>
+=over 4
+
+=back
+
+=item B<get_override_method_modifier>
+
+=item B<get_after_method_modifiers_map>
+
+=item B<get_around_method_modifiers_map>
+
+=item B<get_before_method_modifiers_map>
-=item B<remove_method_modifiers>
+=item B<get_override_method_modifiers_map>
=back