Edit file File name : UsingWithMoose.pod Content :=pod =encoding utf-8 =head1 NAME Type::Tiny::Manual::UsingWithMoose - how to use Type::Tiny with Moose =head1 MANUAL First read L<Type::Tiny::Manual::Moo>, L<Type::Tiny::Manual::Moo2>, and L<Type::Tiny::Manual::Moo3>. Everything in those parts of the manual should work exactly the same in Moose. This part of the manual will focus on Moose-specifics. =head2 Why Use Type::Tiny At All? Moose does have a built-in type constraint system which is fairly convenient to use, but there are several reasons you should consider using Type::Tiny instead. =over =item * Type::Tiny type constraints will usually be faster than Moose built-ins. Even without Type::Tiny::XS installed, Type::Tiny usually produces more efficient inline code than Moose. Coercions will usually be a lot faster. =item * Type::Tiny provides helpful methods like C<where> and C<plus_coercions> that allow type constraints and coercions to be easily tweaked on a per-attribute basis. Something like this is much harder to do with plain Moose types: has name => ( is => "ro", isa => Str->plus_coercions( ArrayRef[Str], sub { join " ", @$_ }, ), coerce => 1, ); Moose tends to encourage defining coercions globally, so if you wanted one B<Str> attribute to be able to coerce from B<< ArrayRef[Str] >>, then I<all> B<Str> attributes would coerce from B<< ArrayRef[Str] >>, and they'd all do that coercion in the same way. (Even if it might make sense to join by a space in some places, a comma in others, and a line break in others!) =item * Type::Tiny provides automatic deep coercions, so if type B<Xyz> has a coercion, the following should "just work": isa xyzlist => ( is => 'ro', isa => ArrayRef[Xyz], coerce => 1 ); =item * Type::Tiny offers a wider selection of built-in types. =item * By using Type::Tiny, you can use the same type constraints and coercions for attributes and method parameters, in Moose and non-Moose code. =back =head2 Type::Utils If you've used L<Moose::Util::TypeConstraints>, you may be accustomed to using a DSL for declaring type constraints: use Moose::Util::TypeConstraints; subtype 'Natural', as 'Int', where { $_ > 0 }; There's a module called L<Type::Utils> that provides a very similar DSL for declaring types in Type::Library-based type libraries. package My::Types { use Type::Library -base; use Type::Utils; use Types::Standard qw( Int ); declare 'Natural', as Int, where { $_ > 0 }; } Personally I prefer the more object-oriented way to declare types though. Since Type::Library 1.012, a shortcut has been available for importing Type::Library and Type::Utils at the same time: package MyType { use Type::Library -base, -utils; ...; } In Moose you might also declare types like this within classes and roles too. Unlike Moose, Type::Tiny doesn't keep types in a single global flat namespace, so this doesn't work quite the same with Type::Utils. It still creates the type, but it doesn't store it in any type library; the type is returned. package My::Class { use Moose; use Type::Utils; use Types::Standard qw( Int ); my $Natural = # store type in a variable declare 'Natural', as Int, where { $_ > 0 }; has number => ( is => 'ro', isa => $Natural ); } But really, isn't the object-oriented way cleaner? package My::Class { use Moose; use Types::Standard qw( Int ); has number => ( is => 'ro', isa => Int->where('$_ > 0'), ); } =head2 Type::Tiny and MooseX::Types L<Types::Standard> should be a drop-in replacement for L<MooseX::Types>. And L<Types::Common::Numeric> and L<Types::Common::String> should easily replace L<MooseX::Types::Common::Numeric> and L<MooseX::Types::Common::String>. That said, if you do with to use a mixture of Type::Tiny and MooseX::Types, they should fit together pretty seamlessly. use Types::Standard qw( ArrayRef ); use MooseX::Types::Common::Numeric qw( PositiveInt ); # this should just work my $list_of_nums = ArrayRef[PositiveInt]; # and this my $list_or_num = ArrayRef | PositiveInt; =head2 C<< -moose >> Import Parameter If you have read this far in the manual, you will know that this is the usual way to import type constraints: use Types::Standard qw( Int ); And the C<Int> which is imported is a function that takes no arguments and returns the B<Int> type constraint, which is a blessed object in the L<Type::Tiny> class. Type::Tiny mocks the L<Moose::Meta::TypeConstraint> API so well that most Moose and MooseX code will not be able to tell the difference. But what if you need a real Moose::Meta::TypeConstraint object? use Types::Standard -moose, qw( Int ); Now the C<Int> function imported will return a genuine native Moose type constraint. This flag is mostly a throwback from when Type::Tiny native objects I<< didn't >> directly work in Moose. In 99.9% of cases, there is no reason to use it and plenty of reasons not to. (Moose native type constraints don't offer helpful methods like C<plus_coercions> and C<where>.) =head2 C<< moose_type >> Method Another quick way to get a native Moose type constraint object from a Type::Tiny object is to call the C<moose_type> method: use Types::Standard qw( Int ); my $tiny_type = Int; my $moose_type = $tiny_type->moose_type; Internally, this is what the C<< -moose >> flag makes imported functions do. =head1 NEXT STEPS Here's your next step: =over =item * L<Type::Tiny::Manual::UsingWithMouse> How to use Type::Tiny with Mouse, including the advantages of Type::Tiny over built-in type constraints, and Mouse-specific features. =back =head1 AUTHOR Toby Inkster E<lt>tobyink@cpan.orgE<gt>. =head1 COPYRIGHT AND LICENCE This software is copyright (c) 2013-2014, 2017-2021 by Toby Inkster. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =head1 DISCLAIMER OF WARRANTIES THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. =cut Save