my ($class, @types) = @_;
my $caller = caller;
- my @type_libs = $class->provide_types_from;
- Class::MOP::load_class($_) for @type_libs;
-
- my %types = map {
- my $lib = $_;
- map +($_ => $lib), $lib->type_names
- } @type_libs;
+ my %types = $class->_provided_types;
my %from;
for my $type (@types) {
- die
- "$caller asked for a type ($type) which is not found in any of the"
- . " type libraries (@type_libs) combined by $class\n"
- unless $types{$type};
+ unless ($types{$type}) {
+ my @type_libs = $class->provide_types_from;
+
+ die
+ "$caller asked for a type ($type) which is not found in any of the"
+ . " type libraries (@type_libs) combined by $class\n";
+ }
push @{ $from{ $types{$type} } }, $type;
}
my $store =
do { no strict 'refs'; \@{ "${class}::__MOOSEX_TYPELIBRARY_LIBRARIES" } };
- @$store = @libs if @libs;
+ if (@libs) {
+ $class->_check_type_lib($_) for @libs;
+ @$store = @libs;
+
+ my %types = map {
+ my $lib = $_;
+ map +( $_ => $lib ), $lib->type_names
+ } @libs;
+
+ $class->_provided_types(%types);
+ }
@$store;
}
+sub _provided_types {
+ my ($class, %types) = @_;
+
+ my $types =
+ do { no strict 'refs'; \%{ "${class}::__MOOSEX_TYPELIBRARY_TYPES" } };
+
+ %$types = %types
+ if keys %types;
+
+ %$types;
+}
+
+sub _check_type_lib {
+ my ($class, $lib) = @_;
+
+ Class::MOP::load_class($lib);
+
+ die "Cannot use $lib in a combined type library, it does not provide any types"
+ unless $lib->can('type_names');
+}
+
=head1 SEE ALSO
L<MooseX::Types>
use strict;
use warnings;
use FindBin;
-use lib "$FindBin::Bin/lib";
+use lib "$FindBin::Bin/lib";
-use Test::More tests => 5;
+use Test::More tests => 7;
use Test::Fatal;
BEGIN { use_ok 'Combined', qw/Foo2Alias MTFNPY NonEmptyStr/ }
like exception { Combined->import('NonExistentType') },
qr/\Qmain asked for a type (NonExistentType) which is not found in any of the type libraries (TestLibrary TestLibrary2) combined by Combined/,
'asking for a non-existent type from a combined type library gives a useful error';
+
+{
+ package BadCombined;
+
+ use base 'MooseX::Types::Combine';
+
+ ::like ::exception { __PACKAGE__->provide_types_from('Empty') },
+ qr/Cannot use Empty in a combined type library, it does not provide any types/,
+ 'cannot combine types from a package which is not a type library';
+
+ ::like ::exception { __PACKAGE__->provide_types_from('DoesNotExist') },
+ qr/Can't locate DoesNotExist\.pm/,
+ 'cannot combine types from a package which does not exist';
+}