X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMoose%2FMeta%2FAttribute%2FNative%2FTrait.pm;h=6727e33c7806d4fc9c6af279a550329ace66e264;hb=a6ae743834ab40ad7ce85880c85cf2c748d423be;hp=a97e3f05f47cb4660165fd76f946aa3cb299b57d;hpb=26a08c157f47d613aab9376a85512ae73ec34482;p=gitmo%2FMoose.git diff --git a/lib/Moose/Meta/Attribute/Native/Trait.pm b/lib/Moose/Meta/Attribute/Native/Trait.pm index a97e3f0..6727e33 100644 --- a/lib/Moose/Meta/Attribute/Native/Trait.pm +++ b/lib/Moose/Meta/Attribute/Native/Trait.pm @@ -3,49 +3,22 @@ package Moose::Meta::Attribute::Native::Trait; use Moose::Role; use Moose::Util::TypeConstraints; -our $VERSION = '0.93_01'; +our $VERSION = '1.14'; $VERSION = eval $VERSION; our $AUTHORITY = 'cpan:STEVAN'; requires '_helper_type'; -# these next two are the possible methods you can use in the 'handles' -# map. - -# provide a Class or Role which we can collect the method providers -# from - -# 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 - }; - }, -); - -# methods called prior to instantiation - before '_process_options' => sub { my ( $self, $name, $options ) = @_; $self->_check_helper_type( $options, $name ); $options->{is} = $self->_default_is - if ! exists $options->{is} && $self->can('_default_is'); + if !exists $options->{is} && $self->can('_default_is'); $options->{default} = $self->_default_default - if ! exists $options->{default} && $self->can('_default_default'); + if !exists $options->{default} && $self->can('_default_default'); }; sub _check_helper_type { @@ -64,8 +37,29 @@ sub _check_helper_type { "The type constraint for $name must be a subtype of $type but it's a $isa"; } +before 'install_accessors' => sub { (shift)->_check_handles_values }; + +sub _check_handles_values { + my $self = shift; + + my $method_constructors = $self->method_constructors; + + my %handles = $self->_canonicalize_handles; + + for my $original_method ( values %handles ) { + my $name = $original_method->[0]; + + my $accessor_class = $self->_native_accessor_class_for($name); + + # XXX - bridge code + ( ( $accessor_class && $accessor_class->can('new') ) + || exists $method_constructors->{$name} ) + || confess "$name is an unsupported method type"; + } +} + around '_canonicalize_handles' => sub { - my $next = shift; + shift; my $self = shift; my $handles = $self->handles; @@ -73,7 +67,7 @@ around '_canonicalize_handles' => sub { unless ( 'HASH' eq ref $handles ) { $self->throw_error( - "The 'handles' option must be a HASH reference, not $handles" ); + "The 'handles' option must be a HASH reference, not $handles"); } return map { @@ -83,48 +77,74 @@ around '_canonicalize_handles' => sub { } keys %$handles; }; -# methods called after instantiation - -before 'install_accessors' => sub { (shift)->_check_handles_values }; - -sub _check_handles_values { - my $self = shift; - - my $method_constructors = $self->method_constructors; +around '_make_delegation_method' => sub { + my $next = shift; + my ( $self, $handle_name, $method_to_call ) = @_; - my %handles = $self->_canonicalize_handles; + my ( $name, @curried_args ) = @$method_to_call; - for my $original_method ( values %handles ) { - my $name = $original_method->[0]; - ( exists $method_constructors->{$name} ) - || confess "$name is an unsupported method type"; + my $accessor_class = $self->_native_accessor_class_for($name); + + # XXX - bridge code + if ( $accessor_class && $accessor_class->can('new') ) { + return $accessor_class->new( + name => $handle_name, + package_name => $self->associated_class->name, + attribute => $self, + curried_arguments => \@curried_args, + root_types => [ $self->_root_types ], + ); } + # XXX - bridge code + else { + my $method_constructors = $self->method_constructors; + + my $code = $method_constructors->{$name}->( + $self, + $self->get_read_method_ref, + $self->get_write_method_ref, + ); + + return $next->( + $self, + $handle_name, + sub { + my $instance = shift; + return $code->( $instance, @curried_args, @_ ); + } + ); + } +}; +sub _root_types { + return $_[0]->_helper_type; } -around '_make_delegation_method' => sub { - my $next = shift; - my ( $self, $handle_name, $method_to_call ) = @_; +sub _native_accessor_class_for { + my ( $self, $suffix ) = @_; - my ( $name, @curried_args ) = @$method_to_call; + # XXX - bridge code + return unless $self->can('_native_type'); - my $method_constructors = $self->method_constructors; + return 'Moose::Meta::Method::Accessor::Native::' . $self->_native_type . '::' . $suffix; +} - my $code = $method_constructors->{$name}->( - $self, - $self->get_read_method_ref, - $self->get_write_method_ref, - ); - - return $next->( - $self, - $handle_name, - sub { - my $instance = shift; - return $code->( $instance, @curried_args, @_ ); - }, - ); -}; +has 'method_constructors' => ( + is => 'ro', + isa => 'HashRef', + lazy => 1, + default => sub { + my $self = shift; + return +{} + unless $self->can('has_method_provider') + && $self->has_method_provider; + + # or grab them from the role/class + my $method_provider = $self->method_provider->meta; + return +{ map { $_->name => $_ } + $method_provider->_get_local_methods }; + }, +); no Moose::Role; no Moose::Util::TypeConstraints;