File Coverage

blib/lib/Moose/Meta/Attribute/Native/Trait.pm
Criterion Covered Total %
statement 51 55 92.7
branch 12 16 75.0
condition 7 15 46.6
subroutine 13 13 100.0
pod n/a
total 83 99 83.8


line stmt bran cond sub pod time code
1             package Moose::Meta::Attribute::Native::Trait;
2             our $VERSION = '2.2205';
3              
4 50     50   29627 use Moose::Role;
  50         166  
  50         381  
5 50     50   795 use Module::Runtime 'require_module';
  50         151  
  50         426  
6 50     50   3898 use Moose::Deprecated;
  50         186  
  50         949  
7 50     50   2731 use Moose::Util 'throw_exception';
  50         142  
  50         1065  
8 50     50   12510 use Moose::Util::TypeConstraints;
  50         536  
  50         841  
9              
10             requires '_helper_type';
11              
12             before '_process_options' => sub {
13             my ( $self, $name, $options ) = @_;
14              
15             $self->_check_helper_type( $options, $name );
16             };
17              
18             sub _check_helper_type {
19 182     182   565 my ( $self, $options, $name ) = @_;
20              
21 182         1074 my $type = $self->_helper_type;
22              
23             $options->{isa} = $type
24 182 100       940 unless exists $options->{isa};
25              
26 182         545 my $isa;
27             my $isa_name;
28              
29 182 50 66     1651 if ( blessed( $options->{isa} )
      33        
30             && $options->{isa}->can('does')
31             && $options->{isa}->does('Specio::Constraint::Role::Interface') ) {
32              
33 0         0 $isa = $options->{isa};
34 0         0 require Specio::Library::Builtins;
35 0 0       0 return if $isa->is_a_type_of( Specio::Library::Builtins::t($type) );
36 0   0     0 $isa_name = $isa->name() || $isa->description();
37             }
38             else {
39             $isa = Moose::Util::TypeConstraints::find_or_create_type_constraint(
40 182         1247 $options->{isa} );
41 182 100       1445 return if $isa->is_a_type_of($type);
42 1         32 $isa_name = $isa->name();
43             }
44              
45 1         13 throw_exception( WrongTypeConstraintGiven => required_type => $type,
46             given_type => $isa_name,
47             attribute_name => $name,
48             params => $options
49             );
50             }
51              
52             before 'install_accessors' => sub { (shift)->_check_handles_values };
53              
54             sub _check_handles_values {
55 181     181   466 my $self = shift;
56              
57 181         899 my %handles = $self->_canonicalize_handles;
58              
59 178         842 for my $original_method ( values %handles ) {
60 1033         3108 my $name = $original_method->[0];
61              
62 1033         2971 my $accessor_class = $self->_native_accessor_class_for($name);
63              
64 1032 50 33     24905 ( $accessor_class && $accessor_class->can('new') )
65             || confess
66             "$name is an unsupported method type - $accessor_class";
67             }
68             }
69              
70             around '_canonicalize_handles' => sub {
71             shift;
72             my $self = shift;
73             my $handles = $self->handles;
74              
75             return unless $handles;
76              
77             unless ( 'HASH' eq ref $handles ) {
78             throw_exception( HandlesMustBeAHashRef => instance => $self,
79             given_handles => $handles
80             );
81             }
82              
83             return
84             map { $_ => $self->_canonicalize_handles_value( $handles->{$_} ) }
85             keys %$handles;
86             };
87              
88             sub _canonicalize_handles_value {
89 2073     2073   3017 my $self = shift;
90 2073         3254 my $value = shift;
91              
92 2073 100 100     5126 if ( ref $value && 'ARRAY' ne ref $value ) {
93 4         21 throw_exception( InvalidHandleValue => instance => $self,
94             handle_value => $value
95             );
96             }
97              
98 2069 100       8214 return ref $value ? $value : [$value];
99             }
100              
101             around '_make_delegation_method' => sub {
102             my $next = shift;
103             my ( $self, $handle_name, $method_to_call ) = @_;
104              
105             my ( $name, @curried_args ) = @$method_to_call;
106              
107             my $accessor_class = $self->_native_accessor_class_for($name);
108              
109             die "Cannot find an accessor class for $name"
110             unless $accessor_class && $accessor_class->can('new');
111              
112             return $accessor_class->new(
113             name => $handle_name,
114             package_name => $self->associated_class->name,
115             delegate_to_method => $name,
116             attribute => $self,
117             is_inline => 1,
118             curried_arguments => \@curried_args,
119             root_types => [ $self->_root_types ],
120             );
121             };
122              
123             sub _root_types {
124 976     976   3623 return $_[0]->_helper_type;
125             }
126              
127             sub _native_accessor_class_for {
128 2065     2065   4315 my ( $self, $suffix ) = @_;
129              
130 2065         77330 my $role
131             = 'Moose::Meta::Method::Accessor::Native::'
132             . $self->_native_type . '::'
133             . $suffix;
134              
135 2064         8432 require_module($role);
136 2064         58502 return Moose::Meta::Class->create_anon_class(
137             superclasses =>
138             [ $self->accessor_metaclass, $self->delegation_metaclass ],
139             roles => [$role],
140             cache => 1,
141             )->name;
142             }
143              
144             sub _build_native_type {
145 177     177   505 my $self = shift;
146              
147 177         800 for my $role_name ( map { $_->name } $self->meta->calculate_all_roles ) {
  372         1921  
148 187 100       7507 return $1 if $role_name =~ /::Native::Trait::(\w+)$/;
149             }
150              
151 1         6 throw_exception( CannotCalculateNativeType => instance => $self );
152             }
153              
154             has '_native_type' => (
155             is => 'ro',
156             isa => 'Str',
157             lazy => 1,
158             builder => '_build_native_type',
159             );
160              
161 50     50   512 no Moose::Role;
  50         146  
  50         269  
162 50     50   416 no Moose::Util::TypeConstraints;
  50         151  
  50         365  
163              
164             1;
165              
166             # ABSTRACT: Shared role for native delegation traits
167              
168             __END__
169              
170             =pod
171              
172             =encoding UTF-8
173              
174             =head1 NAME
175              
176             Moose::Meta::Attribute::Native::Trait - Shared role for native delegation traits
177              
178             =head1 VERSION
179              
180             version 2.2205
181              
182             =head1 BUGS
183              
184             See L<Moose/BUGS> for details on reporting bugs.
185              
186             =head1 SEE ALSO
187              
188             Documentation for Moose native traits can be found in
189             L<Moose::Meta::Attribute::Native>.
190              
191             =head1 AUTHORS
192              
193             =over 4
194              
195             =item *
196              
197             Stevan Little <stevan@cpan.org>
198              
199             =item *
200              
201             Dave Rolsky <autarch@urth.org>
202              
203             =item *
204              
205             Jesse Luehrs <doy@cpan.org>
206              
207             =item *
208              
209             Shawn M Moore <sartak@cpan.org>
210              
211             =item *
212              
213             יובל קוג'מן (Yuval Kogman) <nothingmuch@woobling.org>
214              
215             =item *
216              
217             Karen Etheridge <ether@cpan.org>
218              
219             =item *
220              
221             Florian Ragwitz <rafl@debian.org>
222              
223             =item *
224              
225             Hans Dieter Pearcey <hdp@cpan.org>
226              
227             =item *
228              
229             Chris Prather <chris@prather.org>
230              
231             =item *
232              
233             Matt S Trout <mstrout@cpan.org>
234              
235             =back
236              
237             =head1 COPYRIGHT AND LICENSE
238              
239             This software is copyright (c) 2006 by Infinity Interactive, Inc.
240              
241             This is free software; you can redistribute it and/or modify it under
242             the same terms as the Perl 5 programming language system itself.
243              
244             =cut