File Coverage

blib/lib/MooseX/Types/Combine.pm
Criterion Covered Total %
statement 62 62 100.0
branch 13 14 92.8
condition n/a
subroutine 11 11 100.0
pod 2 2 100.0
total 88 89 98.8


line stmt bran cond sub pod time code
1 2     2   66245 use strict;
  2         6  
  2         65  
2 2     2   11 use warnings;
  2         4  
  2         269  
3             package MooseX::Types::Combine;
4             # ABSTRACT: Combine type libraries for exporting
5              
6             our $VERSION = '0.50';
7              
8 2     2   1299 use Module::Runtime 'use_module';
  2         4456  
  2         13  
9 2     2   1253 use namespace::autoclean;
  2         34261  
  2         9  
10              
11             #pod =head1 SYNOPSIS
12             #pod
13             #pod package CombinedTypeLib;
14             #pod
15             #pod use base 'MooseX::Types::Combine';
16             #pod
17             #pod __PACKAGE__->provide_types_from(qw/TypeLib1 TypeLib2/);
18             #pod
19             #pod package UserClass;
20             #pod
21             #pod use CombinedTypeLib qw/Type1 Type2 ... /;
22             #pod
23             #pod =head1 DESCRIPTION
24             #pod
25             #pod Allows you to create a single class that will allow you to export types from
26             #pod multiple type libraries:
27             #pod
28             #pod package TransportTypes;
29             #pod
30             #pod use base 'MooseX::Types::Combine';
31             #pod
32             #pod __PACKAGE__->provide_types_from(qw/ MotorizedTypes UnmotorizedTypes /);
33             #pod
34             #pod 1;
35             #pod
36             #pod In this example all types defined in C<MotorizedTypes> and C<UnmotorizedTypes>
37             #pod are available through the C<TransportTypes> combined type library.
38             #pod
39             #pod package SkiingTrip;
40             #pod
41             #pod use Moose;
42             #pod
43             #pod use TransportTypes qw( CarType SkisType );
44             #pod
45             #pod has car => ( is => 'ro', isa => CarType, required => 1 );
46             #pod has ski_rack => ( is => 'ro', isa => ArrayRef[SkisType], required => 1 );
47             #pod ...
48             #pod
49             #pod Libraries on the right end of the list passed to L</provide_types_from> take
50             #pod precedence over those on the left in case of conflicts. So, in the above
51             #pod example if both the C<MotorizedTypes> and C<UnmotorizedTypes> libraries provided
52             #pod a C<Bike> type, you'd get the bicycle from C<UnmotorizedTypes> not the
53             #pod motorbike from C<MorotizedTypes>.
54             #pod
55             #pod You can also further combine combined type libraries with additional type
56             #pod libraries or other combined type libraries in the same way to provide even
57             #pod larger type libraries:
58             #pod
59             #pod package MeetingTransportTypes;
60             #pod
61             #pod use base 'MooseX::Types::Combine';
62             #pod
63             #pod __PACKAGE__->provide_types_from(qw/ TransportTypes TelepresenceTypes /);
64             #pod
65             #pod 1;
66             #pod
67             #pod =cut
68              
69             sub import {
70 5     5   1354 my ($class, @types) = @_;
71 5         9 my $caller = caller;
72              
73 5         5 my $where_to_import_to = $caller;
74 5 100       17 if (ref $types[0] eq 'HASH') {
75 1         2 my $extra = shift @types;
76 1 50       4 $where_to_import_to = $extra->{-into} if exists $extra->{-into};
77             }
78              
79 5         14 my %types = $class->_provided_types;
80              
81 5 100       10 if ( grep { $_ eq ':all' } @types ) {
  9         22  
82             $_->import( { -into => $where_to_import_to }, q{:all} )
83 1         4 for $class->provide_types_from;
84 1         233 return;
85             }
86              
87 4         5 my %from;
88 4         8 for my $type (@types) {
89 8 100       16 unless ($types{$type}) {
90 1         5 my @type_libs = $class->provide_types_from;
91              
92 1         14 die
93             "$caller asked for a type ($type) which is not found in any of the"
94             . " type libraries (@type_libs) combined by $class\n";
95             }
96              
97 7         7 push @{ $from{ $types{$type} } }, $type;
  7         13  
98             }
99              
100 5         283 $_->import({ -into => $where_to_import_to }, @{ $from{ $_ } })
101 3         14 for keys %from;
102             }
103              
104             #pod =head1 CLASS METHODS
105             #pod
106             #pod =head2 provide_types_from
107             #pod
108             #pod Sets or returns a list of type libraries (or combined type libraries) to
109             #pod re-export from.
110             #pod
111             #pod =cut
112              
113             sub provide_types_from {
114 7     7 1 1470 my ($class, @libs) = @_;
115              
116             my $store =
117 2     2   901 do { no strict 'refs'; \@{ "${class}::__MOOSEX_TYPELIBRARY_LIBRARIES" } };
  2         4  
  2         516  
  7         11  
  7         8  
  7         29  
118              
119 7 100       23 if (@libs) {
120 5         26 $class->_check_type_lib($_) for @libs;
121 3         9 @$store = @libs;
122              
123             my %types = map {
124 3         6 my $lib = $_;
  5         5  
125 5         21 map +( $_ => $lib ), $lib->type_names
126             } @libs;
127              
128 3         27 $class->_provided_types(%types);
129             }
130              
131 5         28 @$store;
132             }
133              
134             sub _check_type_lib {
135 7     7   14 my ($class, $lib) = @_;
136              
137 7         45 use_module($lib);
138              
139 6 100       3489 die "Cannot use $lib in a combined type library, it does not provide any types"
140             unless $lib->can('type_names');
141             }
142              
143             sub _provided_types {
144 9     9   16 my ($class, %types) = @_;
145              
146             my $types =
147 2     2   12 do { no strict 'refs'; \%{ "${class}::__MOOSEX_TYPELIBRARY_TYPES" } };
  2         4  
  2         293  
  9         8  
  9         7  
  9         27  
148              
149 9 100       26 %$types = %types
150             if keys %types;
151              
152 9         35 %$types;
153             }
154              
155             #pod =head2 type_names
156             #pod
157             #pod Returns a list of all known types by their name.
158             #pod
159             #pod =cut
160              
161             sub type_names {
162 1     1 1 3 my ($class) = @_;
163              
164 1         3 my %types = $class->_provided_types();
165 1         6 return keys %types;
166             }
167              
168             #pod =head1 SEE ALSO
169             #pod
170             #pod L<MooseX::Types>
171             #pod
172             #pod =cut
173              
174             1;
175              
176             __END__
177              
178             =pod
179              
180             =encoding UTF-8
181              
182             =head1 NAME
183              
184             MooseX::Types::Combine - Combine type libraries for exporting
185              
186             =head1 VERSION
187              
188             version 0.50
189              
190             =head1 SYNOPSIS
191              
192             package CombinedTypeLib;
193              
194             use base 'MooseX::Types::Combine';
195              
196             __PACKAGE__->provide_types_from(qw/TypeLib1 TypeLib2/);
197              
198             package UserClass;
199              
200             use CombinedTypeLib qw/Type1 Type2 ... /;
201              
202             =head1 DESCRIPTION
203              
204             Allows you to create a single class that will allow you to export types from
205             multiple type libraries:
206              
207             package TransportTypes;
208              
209             use base 'MooseX::Types::Combine';
210              
211             __PACKAGE__->provide_types_from(qw/ MotorizedTypes UnmotorizedTypes /);
212              
213             1;
214              
215             In this example all types defined in C<MotorizedTypes> and C<UnmotorizedTypes>
216             are available through the C<TransportTypes> combined type library.
217              
218             package SkiingTrip;
219              
220             use Moose;
221              
222             use TransportTypes qw( CarType SkisType );
223              
224             has car => ( is => 'ro', isa => CarType, required => 1 );
225             has ski_rack => ( is => 'ro', isa => ArrayRef[SkisType], required => 1 );
226             ...
227              
228             Libraries on the right end of the list passed to L</provide_types_from> take
229             precedence over those on the left in case of conflicts. So, in the above
230             example if both the C<MotorizedTypes> and C<UnmotorizedTypes> libraries provided
231             a C<Bike> type, you'd get the bicycle from C<UnmotorizedTypes> not the
232             motorbike from C<MorotizedTypes>.
233              
234             You can also further combine combined type libraries with additional type
235             libraries or other combined type libraries in the same way to provide even
236             larger type libraries:
237              
238             package MeetingTransportTypes;
239              
240             use base 'MooseX::Types::Combine';
241              
242             __PACKAGE__->provide_types_from(qw/ TransportTypes TelepresenceTypes /);
243              
244             1;
245              
246             =head1 CLASS METHODS
247              
248             =head2 provide_types_from
249              
250             Sets or returns a list of type libraries (or combined type libraries) to
251             re-export from.
252              
253             =head2 type_names
254              
255             Returns a list of all known types by their name.
256              
257             =head1 SEE ALSO
258              
259             L<MooseX::Types>
260              
261             =head1 SUPPORT
262              
263             Bugs may be submitted through L<the RT bug tracker|https://rt.cpan.org/Public/Dist/Display.html?Name=MooseX-Types>
264             (or L<bug-MooseX-Types@rt.cpan.org|mailto:bug-MooseX-Types@rt.cpan.org>).
265              
266             There is also a mailing list available for users of this distribution, at
267             L<http://lists.perl.org/list/moose.html>.
268              
269             There is also an irc channel available for users of this distribution, at
270             L<C<#moose> on C<irc.perl.org>|irc://irc.perl.org/#moose>.
271              
272             =head1 AUTHOR
273              
274             Robert "phaylon" Sedlacek <rs@474.at>
275              
276             =head1 COPYRIGHT AND LICENCE
277              
278             This software is copyright (c) 2007 by Robert "phaylon" Sedlacek.
279              
280             This is free software; you can redistribute it and/or modify it under
281             the same terms as the Perl 5 programming language system itself.
282              
283             =cut