5 MooseX::Types - Organise your Moose types in libraries
12 use Moose::Util::TypeConstraints;
13 use MooseX::Types::Base ();
14 use MooseX::Types::Util qw( filter_tags );
15 use MooseX::Types::UndefinedType;
16 use Sub::Install qw( install_sub );
20 use namespace::clean -except => [qw( meta )];
24 my $UndefMsg = q{Action for type '%s' not yet defined in library '%s'};
28 =head2 Library Definition
32 # predeclare our own types
34 -declare => [qw( PositiveInt NegativeInt )];
36 # import builtin types
37 use MooseX::Types::Moose 'Int';
43 message { "Int is not larger than 0" };
48 message { "Int is not smaller than 0" };
61 use MyLibrary qw( PositiveInt NegativeInt );
63 # use the exported constants as type names
75 print "positive\n" if is_PositiveInt($value);
76 print "negative\n" if is_NegativeInt($value);
78 # coerce the value, NegativeInt doesn't have a coercion
79 # helper, since it didn't define any coercions.
80 $value = to_PositiveInt($value) or die "Cannot coerce";
87 The types provided with L<Moose> are by design global. This package helps
88 you to organise and selectively import your own and the built-in types in
89 libraries. As a nice side effect, it catches typos at compile-time too.
91 However, the main reason for this module is to provide an easy way to not
92 have conflicts with your type names, since the internal fully qualified
93 names of the types will be prefixed with the library's name.
95 This module will also provide you with some helper functions to make it
96 easier to use Moose types in your code.
98 =head1 TYPE HANDLER FUNCTIONS
102 A constant with the name of your type. It contains the type's fully
103 qualified name. Takes no value, as all constants.
107 This handler takes a value and tests if it is a valid value for this
108 C<$type>. It will return true or false.
112 A handler that will take a value and coerce it into the C<$type>. It will
113 return a false value if the type could not be coerced.
115 B<Important Note>: This handler will only be exported for types that can
116 do type coercion. This has the advantage that a coercion to a type that
117 cannot hasn't defined any coercions will lead to a compile-time error.
119 =head1 LIBRARY DEFINITION
121 A MooseX::Types is just a normal Perl module. Unlike Moose
122 itself, it does not install C<use strict> and C<use warnings> in your
123 class by default, so this is up to you.
125 The only thing a library is required to do is
127 use MooseX::Types -declare => \@types;
129 with C<@types> being a list of types you wish to define in this library.
130 This line will install a proper base class in your package as well as the
131 full set of L<handlers|/"TYPE HANDLER FUNCTIONS"> for your declared
132 types. It will then hand control over to L<Moose::Util::TypeConstraints>'
133 C<import> method to export the functions you will need to declare your
136 If you want to use Moose' built-in types (e.g. for subtyping) you will
139 use MooseX::Types::Moose @types;
141 to import the helpers from the shipped L<MooseX::Types::Moose>
142 library which can export all types that come with Moose.
144 You will have to define coercions for your types or your library won't
145 export a L</to_$type> coercion helper for it.
147 Note that you currently cannot define types containing C<::>, since
148 exporting would be a problem.
150 You also don't need to use C<warnings> and C<strict>, since the
151 definition of a library automatically exports those.
155 You can import the L<"type helpers"|/"TYPE HANDLER FUNCTIONS"> of a
156 library by C<use>ing it with a list of types to import as arguments. If
157 you want all of them, use the C<:all> tag. For example:
159 use MyLibrary ':all';
160 use MyOtherLibrary qw( TypeA TypeB );
162 MooseX::Types comes with a library of Moose' built-in types called
163 L<MooseX::Types::Moose>.
165 =head1 WRAPPING A LIBRARY
167 You can define your own wrapper subclasses to manipulate the behaviour
168 of a set of library exports. Here is an example:
173 use base 'MooseX::Types::Wrapper';
175 sub coercion_export_generator {
177 my $code = $class->next::method(@_);
179 my $value = $code->(@_);
180 warn "Coercion returned undef!"
181 unless defined $value;
188 This class wraps the coercion generator (e.g., C<to_Int()>) and warns
189 if a coercion returned an undefined value. You can wrap any library
194 use MyWrapper MyLibrary => [qw( Foo Bar )],
195 Moose => [qw( Str Int )];
200 The C<Moose> library name is a special shortcut for
201 L<MooseX::Types::Moose>.
203 =head2 Generator methods you can overload
207 =item type_export_generator( $short, $full )
209 Creates a closure returning the type's L<Moose::Meta::TypeConstraint>
212 =item check_export_generator( $short, $full, $undef_message )
214 This creates the closure used to test if a value is valid for this type.
216 =item coercion_export_generator( $short, $full, $undef_message )
218 This is the closure that's doing coercions.
222 =head2 Provided Parameters
228 The short, exported name of the type.
232 The fully qualified name of this type as L<Moose> knows it.
236 A message that will be thrown when type functionality is used but the
237 type does not yet exist.
245 Installs the L<MooseX::Types::Base> class into the caller and
246 exports types according to the specification described in
247 L</"LIBRARY DEFINITION">. This will continue to
248 L<Moose::Util::TypeConstraints>' C<import> method to export helper
249 functions you will need to declare your types.
254 my ($class, %args) = @_;
257 # everyone should want this
261 # inject base class into new library
263 unshift @{ $callee . '::ISA' }, 'MooseX::Types::Base';
266 # generate predeclared type helpers
267 if (my @orig_declare = @{ $args{ -declare } || [] }) {
268 my ($tags, $declare) = filter_tags @orig_declare;
270 for my $type (@$declare) {
272 croak "Cannot create a type containing '::' ($type) at the moment"
275 $callee->add_type($type);
276 $callee->export_type_into(
278 sprintf($UndefMsg, $type, $callee),
284 # run type constraints import
285 return Moose::Util::TypeConstraints->import({ into => $callee });
288 =head2 type_export_generator
290 Generate a type export, e.g. C<Int()>. This will return either a
291 L<Moose::Meta::TypeConstraint> object, or alternatively a
292 L<MooseX::Types::UndefinedType> object if the type was not
297 sub type_export_generator {
298 my ($class, $type, $full) = @_;
300 return find_type_constraint($full)
301 || MooseX::Types::UndefinedType->new($full);
305 =head2 coercion_export_generator
307 This generates a coercion handler function, e.g. C<to_Int($value)>.
311 sub coercion_export_generator {
312 my ($class, $type, $full, $undef_msg) = @_;
316 # we need a type object
317 my $tobj = find_type_constraint($full) or croak $undef_msg;
318 my $return = $tobj->coerce($value);
320 # non-successful coercion returns false
321 return unless $tobj->check($return);
327 =head2 check_export_generator
329 Generates a constraint check closure, e.g. C<is_Int($value)>.
333 sub check_export_generator {
334 my ($class, $type, $full, $undef_msg) = @_;
338 # we need a type object
339 my $tobj = find_type_constraint($full) or croak $undef_msg;
341 return $tobj->check($value);
347 A library makes the types quasi-unique by prefixing their names with (by
348 default) the library package name. If you're only using the type handler
349 functions provided by MooseX::Types, you shouldn't ever have to use
350 a type's actual full name.
354 L<Moose>, L<Moose::Util::TypeConstraints>, L<MooseX::Types::Moose>
356 =head1 AUTHOR AND COPYRIGHT
358 Robert 'phaylon' Sedlacek C<E<lt>rs@474.atE<gt>>, with many thanks to
359 the C<#moose> cabal on C<irc.perl.org>.
363 This program is free software; you can redistribute it and/or modify
364 it under the same terms as perl itself.