X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMooseX%2FAttributeHelpers%2FBase.pm;h=77631ee9de3f4bda645173b7ac598804ecaf0aa9;hb=5431dff2bf81c8286d40150d9f87a42a2a3e994c;hp=267ffbe109bed08e761d28e7972145eeb6cc38d8;hpb=8ba40fb0b088c42192cad9bd39f45cfef520a975;p=gitmo%2FMooseX-AttributeHelpers.git diff --git a/lib/MooseX/AttributeHelpers/Base.pm b/lib/MooseX/AttributeHelpers/Base.pm index 267ffbe..77631ee 100644 --- a/lib/MooseX/AttributeHelpers/Base.pm +++ b/lib/MooseX/AttributeHelpers/Base.pm @@ -8,16 +8,43 @@ our $AUTHORITY = 'cpan:STEVAN'; extends 'Moose::Meta::Attribute'; -has 'method_constructors' => ( +# this is the method map you define ... +has 'provides' => ( is => 'ro', isa => 'HashRef', - default => sub { {} } + default => sub {{}} ); -has 'provides' => ( - is => 'ro', - isa => 'HashRef', - required => 1, + +# these next two are the possible methods +# you can use in the 'provides' map. + +# provide a Class or Role which we can +# collect the method providers from +has 'method_provider' => ( + is => 'ro', + isa => 'ClassName', + predicate => 'has_method_provider', +); + +# or you can provide a HASH ref of anon subs +# yourself. This will also collect and store +# the methods from a method_provider as well +has 'method_constructors' => ( + is => 'ro', + isa => 'HashRef', + lazy => 1, + default => sub { + my $self = shift; + return +{} unless $self->has_method_provider; + # or grab them from the role/class + my $method_provider = $self->method_provider->meta; + return +{ + map { + $_ => $method_provider->get_method($_) + } $method_provider->get_method_list + }; + }, ); # extend the parents stuff to make sure @@ -31,11 +58,12 @@ sub helper_type { () } sub process_options_for_provides { my ($self, $options) = @_; + if (my $type = $self->helper_type) { (exists $options->{isa}) || confess "You must define a type with the $type metaclass"; - my $isa = $options->{isa}; + my $isa = $options->{isa}; unless (blessed($isa) && $isa->isa('Moose::Meta::TypeConstraint')) { $isa = find_type_constraint($isa); @@ -44,14 +72,12 @@ sub process_options_for_provides { ($isa->is_a_type_of($type)) || confess "The type constraint for a $type ($options->{isa}) must be a subtype of $type"; } - - # this can be augmented by subclasses .. - inner(); } before '_process_options' => sub { my ($self, $name, $options) = @_; - if (exists $options->{provides}) { + if (exists $options->{provides} || + exists $options->{isa} && $options->{isa} =~ /^.*?\[.*?\]$/) { $self->process_options_for_provides($options); } }; @@ -62,7 +88,9 @@ before '_process_options' => sub { # all valid possibilities in it sub check_provides_values { my $self = shift; + my $method_constructors = $self->method_constructors; + foreach my $key (keys %{$self->provides}) { (exists $method_constructors->{$key}) || confess "$key is an unsupported method type"; @@ -80,9 +108,18 @@ after 'install_accessors' => sub { my $method_constructors = $attr->method_constructors; foreach my $key (keys %{$attr->provides}) { - $class->add_method( - $attr->provides->{$key}, - $method_constructors->{$key}->($attr) + + my $method_name = $attr->provides->{$key}; + my $method_body = $method_constructors->{$key}->($attr); + + if ($class->has_method($method_name)) { + confess "The method ($method_name) already exists in class (" . $class->name . ")"; + } + + $class->add_method($method_name => + MooseX::AttributeHelpers::Meta::Method::Provided->wrap( + $method_body, + ) ); } }; @@ -98,14 +135,58 @@ __END__ =head1 NAME -MooseX::AttributeHelpers::Base - -=head1 SYNOPSIS +MooseX::AttributeHelpers::Base - Base class for attribute helpers =head1 DESCRIPTION +Documentation to come. + +=head1 ATTRIBUTES + +=over 4 + +=item B + +=item B + +=item B + +=back + +=head1 EXTENDED ATTRIBUTES + +=over 4 + +=item B<$!default> + +C<$!default> is now required. + +=item B + +C is now required. + +=back + =head1 METHODS +=over 4 + +=item B + +=item B + +=item B + +=item B + +=item B + +=item B + +=item B + +=back + =head1 BUGS All complex software has bugs lurking in it, and this module is no