245 lines
5.4 KiB
Perl
245 lines
5.4 KiB
Perl
package Moose::Meta::Attribute::Native::Trait;
|
|
our $VERSION = '2.2207';
|
|
|
|
use Moose::Role;
|
|
use Module::Runtime 'require_module';
|
|
use Moose::Deprecated;
|
|
use Moose::Util 'throw_exception';
|
|
use Moose::Util::TypeConstraints;
|
|
|
|
requires '_helper_type';
|
|
|
|
before '_process_options' => sub {
|
|
my ( $self, $name, $options ) = @_;
|
|
|
|
$self->_check_helper_type( $options, $name );
|
|
};
|
|
|
|
sub _check_helper_type {
|
|
my ( $self, $options, $name ) = @_;
|
|
|
|
my $type = $self->_helper_type;
|
|
|
|
$options->{isa} = $type
|
|
unless exists $options->{isa};
|
|
|
|
my $isa;
|
|
my $isa_name;
|
|
|
|
if ( blessed( $options->{isa} )
|
|
&& $options->{isa}->can('does')
|
|
&& $options->{isa}->does('Specio::Constraint::Role::Interface') ) {
|
|
|
|
$isa = $options->{isa};
|
|
require Specio::Library::Builtins;
|
|
return if $isa->is_a_type_of( Specio::Library::Builtins::t($type) );
|
|
$isa_name = $isa->name() || $isa->description();
|
|
}
|
|
else {
|
|
$isa = Moose::Util::TypeConstraints::find_or_create_type_constraint(
|
|
$options->{isa} );
|
|
return if $isa->is_a_type_of($type);
|
|
$isa_name = $isa->name();
|
|
}
|
|
|
|
throw_exception( WrongTypeConstraintGiven => required_type => $type,
|
|
given_type => $isa_name,
|
|
attribute_name => $name,
|
|
params => $options
|
|
);
|
|
}
|
|
|
|
before 'install_accessors' => sub { (shift)->_check_handles_values };
|
|
|
|
sub _check_handles_values {
|
|
my $self = shift;
|
|
|
|
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);
|
|
|
|
( $accessor_class && $accessor_class->can('new') )
|
|
|| confess
|
|
"$name is an unsupported method type - $accessor_class";
|
|
}
|
|
}
|
|
|
|
around '_canonicalize_handles' => sub {
|
|
shift;
|
|
my $self = shift;
|
|
my $handles = $self->handles;
|
|
|
|
return unless $handles;
|
|
|
|
unless ( 'HASH' eq ref $handles ) {
|
|
throw_exception( HandlesMustBeAHashRef => instance => $self,
|
|
given_handles => $handles
|
|
);
|
|
}
|
|
|
|
return
|
|
map { $_ => $self->_canonicalize_handles_value( $handles->{$_} ) }
|
|
keys %$handles;
|
|
};
|
|
|
|
sub _canonicalize_handles_value {
|
|
my $self = shift;
|
|
my $value = shift;
|
|
|
|
if ( ref $value && 'ARRAY' ne ref $value ) {
|
|
throw_exception( InvalidHandleValue => instance => $self,
|
|
handle_value => $value
|
|
);
|
|
}
|
|
|
|
return ref $value ? $value : [$value];
|
|
}
|
|
|
|
around '_make_delegation_method' => sub {
|
|
my $next = shift;
|
|
my ( $self, $handle_name, $method_to_call ) = @_;
|
|
|
|
my ( $name, @curried_args ) = @$method_to_call;
|
|
|
|
my $accessor_class = $self->_native_accessor_class_for($name);
|
|
|
|
die "Cannot find an accessor class for $name"
|
|
unless $accessor_class && $accessor_class->can('new');
|
|
|
|
return $accessor_class->new(
|
|
name => $handle_name,
|
|
package_name => $self->associated_class->name,
|
|
delegate_to_method => $name,
|
|
attribute => $self,
|
|
is_inline => 1,
|
|
curried_arguments => \@curried_args,
|
|
root_types => [ $self->_root_types ],
|
|
);
|
|
};
|
|
|
|
sub _root_types {
|
|
return $_[0]->_helper_type;
|
|
}
|
|
|
|
sub _native_accessor_class_for {
|
|
my ( $self, $suffix ) = @_;
|
|
|
|
my $role
|
|
= 'Moose::Meta::Method::Accessor::Native::'
|
|
. $self->_native_type . '::'
|
|
. $suffix;
|
|
|
|
require_module($role);
|
|
return Moose::Meta::Class->create_anon_class(
|
|
superclasses =>
|
|
[ $self->accessor_metaclass, $self->delegation_metaclass ],
|
|
roles => [$role],
|
|
cache => 1,
|
|
)->name;
|
|
}
|
|
|
|
sub _build_native_type {
|
|
my $self = shift;
|
|
|
|
for my $role_name ( map { $_->name } $self->meta->calculate_all_roles ) {
|
|
return $1 if $role_name =~ /::Native::Trait::(\w+)$/;
|
|
}
|
|
|
|
throw_exception( CannotCalculateNativeType => instance => $self );
|
|
}
|
|
|
|
has '_native_type' => (
|
|
is => 'ro',
|
|
isa => 'Str',
|
|
lazy => 1,
|
|
builder => '_build_native_type',
|
|
);
|
|
|
|
no Moose::Role;
|
|
no Moose::Util::TypeConstraints;
|
|
|
|
1;
|
|
|
|
# ABSTRACT: Shared role for native delegation traits
|
|
|
|
__END__
|
|
|
|
=pod
|
|
|
|
=encoding UTF-8
|
|
|
|
=head1 NAME
|
|
|
|
Moose::Meta::Attribute::Native::Trait - Shared role for native delegation traits
|
|
|
|
=head1 VERSION
|
|
|
|
version 2.2207
|
|
|
|
=head1 BUGS
|
|
|
|
See L<Moose/BUGS> for details on reporting bugs.
|
|
|
|
=head1 SEE ALSO
|
|
|
|
Documentation for Moose native traits can be found in
|
|
L<Moose::Meta::Attribute::Native>.
|
|
|
|
=head1 AUTHORS
|
|
|
|
=over 4
|
|
|
|
=item *
|
|
|
|
Stevan Little <stevan@cpan.org>
|
|
|
|
=item *
|
|
|
|
Dave Rolsky <autarch@urth.org>
|
|
|
|
=item *
|
|
|
|
Jesse Luehrs <doy@cpan.org>
|
|
|
|
=item *
|
|
|
|
Shawn M Moore <sartak@cpan.org>
|
|
|
|
=item *
|
|
|
|
יובל קוג'מן (Yuval Kogman) <nothingmuch@woobling.org>
|
|
|
|
=item *
|
|
|
|
Karen Etheridge <ether@cpan.org>
|
|
|
|
=item *
|
|
|
|
Florian Ragwitz <rafl@debian.org>
|
|
|
|
=item *
|
|
|
|
Hans Dieter Pearcey <hdp@cpan.org>
|
|
|
|
=item *
|
|
|
|
Chris Prather <chris@prather.org>
|
|
|
|
=item *
|
|
|
|
Matt S Trout <mstrout@cpan.org>
|
|
|
|
=back
|
|
|
|
=head1 COPYRIGHT AND LICENSE
|
|
|
|
This software is copyright (c) 2006 by Infinity Interactive, Inc.
|
|
|
|
This is free software; you can redistribute it and/or modify it under
|
|
the same terms as the Perl 5 programming language system itself.
|
|
|
|
=cut
|