This commit is contained in:
244
CPAN/Moose/Meta/Attribute/Native/Trait.pm
Normal file
244
CPAN/Moose/Meta/Attribute/Native/Trait.pm
Normal file
@@ -0,0 +1,244 @@
|
||||
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
|
||||
Reference in New Issue
Block a user