added auto-strict and warnings, finished off 0.04
[gitmo/MooseX-Types.git] / lib / MooseX / Types.pm
1 package MooseX::Types;
2
3 =head1 NAME
4
5 MooseX::Types - Organise your Moose types in libraries
6
7 =cut
8
9 #use warnings;
10 #use strict;
11
12 use Sub::Uplevel;
13 use Moose::Util::TypeConstraints;
14 use MooseX::Types::Base             ();
15 use MooseX::Types::Util             qw( filter_tags );
16 use MooseX::Types::UndefinedType;
17 use Sub::Install                    qw( install_sub );
18 use Carp                            qw( croak );
19 use Moose;
20
21 use namespace::clean -except => [qw( meta )];
22
23 our $VERSION = 0.04;
24
25 my $UndefMsg = q{Action for type '%s' not yet defined in library '%s'};
26
27 =head1 SYNOPSIS
28
29 =head2 Library Definition
30
31   package MyLibrary;
32
33   # predeclare our own types
34   use MooseX::Types 
35       -declare => [qw( PositiveInt NegativeInt )];
36
37   # import builtin types
38   use MooseX::Types::Moose 'Int';
39
40   # type definition
41   subtype PositiveInt, 
42       as Int, 
43       where { $_ > 0 },
44       message { "Int is not larger than 0" };
45   
46   subtype NegativeInt,
47       as Int,
48       where { $_ < 0 },
49       message { "Int is not smaller than 0" };
50
51   # type coercion
52   coerce PositiveInt,
53       from Int,
54           via { 1 };
55
56   1;
57
58 =head2 Usage
59
60   package Foo;
61   use Moose;
62   use MyLibrary qw( PositiveInt NegativeInt );
63
64   # use the exported constants as type names
65   has 'bar',
66       isa    => PositiveInt,
67       is     => 'rw';
68   has 'baz',
69       isa    => NegativeInt,
70       is     => 'rw';
71
72   sub quux {
73       my ($self, $value);
74
75       # test the value
76       print "positive\n" if is_PositiveInt($value);
77       print "negative\n" if is_NegativeInt($value);
78
79       # coerce the value, NegativeInt doesn't have a coercion
80       # helper, since it didn't define any coercions.
81       $value = to_PositiveInt($value) or die "Cannot coerce";
82   }
83
84   1;
85
86 =head1 DESCRIPTION
87
88 The types provided with L<Moose> are by design global. This package helps
89 you to organise and selectively import your own and the built-in types in
90 libraries. As a nice side effect, it catches typos at compile-time too.
91
92 However, the main reason for this module is to provide an easy way to not
93 have conflicts with your type names, since the internal fully qualified
94 names of the types will be prefixed with the library's name.
95
96 This module will also provide you with some helper functions to make it 
97 easier to use Moose types in your code.
98
99 =head1 TYPE HANDLER FUNCTIONS
100
101 =head2 $type
102
103 A constant with the name of your type. It contains the type's fully
104 qualified name. Takes no value, as all constants.
105
106 =head2 is_$type
107
108 This handler takes a value and tests if it is a valid value for this
109 C<$type>. It will return true or false.
110
111 =head2 to_$type
112
113 A handler that will take a value and coerce it into the C<$type>. It will
114 return a false value if the type could not be coerced.
115
116 B<Important Note>: This handler will only be exported for types that can
117 do type coercion. This has the advantage that a coercion to a type that
118 cannot hasn't defined any coercions will lead to a compile-time error.
119
120 =head1 LIBRARY DEFINITION
121
122 A MooseX::Types is just a normal Perl module. Unlike Moose 
123 itself, it does not install C<use strict> and C<use warnings> in your
124 class by default, so this is up to you.
125
126 The only thing a library is required to do is
127
128   use MooseX::Types -declare => \@types;
129
130 with C<@types> being a list of types you wish to define in this library.
131 This line will install a proper base class in your package as well as the
132 full set of L<handlers|/"TYPE HANDLER FUNCTIONS"> for your declared 
133 types. It will then hand control over to L<Moose::Util::TypeConstraints>'
134 C<import> method to export the functions you will need to declare your
135 types.
136
137 If you want to use Moose' built-in types (e.g. for subtyping) you will 
138 want to 
139
140   use MooseX::Types::Moose @types;
141
142 to import the helpers from the shipped L<MooseX::Types::Moose>
143 library which can export all types that come with Moose.
144
145 You will have to define coercions for your types or your library won't
146 export a L</to_$type> coercion helper for it.
147
148 Note that you currently cannot define types containing C<::>, since 
149 exporting would be a problem.
150
151 You also don't need to use C<warnings> and C<strict>, since the
152 definition of a library automatically exports those.
153
154 =head1 LIBRARY USAGE
155
156 You can import the L<"type helpers"|/"TYPE HANDLER FUNCTIONS"> of a
157 library by C<use>ing it with a list of types to import as arguments. If
158 you want all of them, use the C<:all> tag. For example:
159
160   use MyLibrary      ':all';
161   use MyOtherLibrary qw( TypeA TypeB );
162
163 MooseX::Types comes with a library of Moose' built-in types called
164 L<MooseX::Types::Moose>.
165
166 =head1 WRAPPING A LIBRARY
167
168 You can define your own wrapper subclasses to manipulate the behaviour
169 of a set of library exports. Here is an example:
170
171   package MyWrapper;
172   use strict;
173   use Class::C3;
174   use base 'MooseX::Types::Wrapper';
175
176   sub coercion_export_generator {
177       my $class = shift;
178       my $code = $class->next::method(@_);
179       return sub {
180           my $value = $code->(@_);
181           warn "Coercion returned undef!"
182               unless defined $value;
183           return $value;
184       };
185   }
186
187   1;
188
189 This class wraps the coercion generator (e.g., C<to_Int()>) and warns
190 if a coercion returned an undefined value. You can wrap any library
191 with this:
192
193   package Foo;
194   use strict;
195   use MyWrapper MyLibrary => [qw( Foo Bar )],
196                 Moose     => [qw( Str Int )];
197
198   ...
199   1;
200
201 The C<Moose> library name is a special shortcut for 
202 L<MooseX::Types::Moose>.
203
204 =head2 Generator methods you can overload
205
206 =over 4
207
208 =item type_export_generator( $short, $full )
209
210 Creates a closure returning the type's L<Moose::Meta::TypeConstraint> 
211 object. 
212
213 =item check_export_generator( $short, $full, $undef_message )
214
215 This creates the closure used to test if a value is valid for this type.
216
217 =item coercion_export_generator( $short, $full, $undef_message )
218
219 This is the closure that's doing coercions.
220
221 =back
222
223 =head2 Provided Parameters
224
225 =over 4
226
227 =item $short
228
229 The short, exported name of the type.
230
231 =item $full
232
233 The fully qualified name of this type as L<Moose> knows it.
234
235 =item $undef_message
236
237 A message that will be thrown when type functionality is used but the
238 type does not yet exist.
239
240 =back
241
242 =head1 METHODS
243
244 =head2 import
245
246 Installs the L<MooseX::Types::Base> class into the caller and 
247 exports types according to the specification described in 
248 L</"LIBRARY DEFINITION">. This will continue to 
249 L<Moose::Util::TypeConstraints>' C<import> method to export helper
250 functions you will need to declare your types.
251
252 =cut
253
254 sub import {
255     my ($class, %args) = @_;
256     my  $callee = caller;
257
258     # everyone should want this
259     strict->import;
260     warnings->import;
261
262     # inject base class into new library
263     {   no strict 'refs';
264         unshift @{ $callee . '::ISA' }, 'MooseX::Types::Base';
265     }
266
267     # generate predeclared type helpers
268     if (my @orig_declare = @{ $args{ -declare } || [] }) {
269         my ($tags, $declare) = filter_tags @orig_declare;
270
271         for my $type (@$declare) {
272
273             croak "Cannot create a type containing '::' ($type) at the moment"
274                 if $type =~ /::/;
275
276             $callee->add_type($type);
277             $callee->export_type_into(
278                 $callee, $type, 
279                 sprintf($UndefMsg, $type, $callee), 
280                 -full => 1,
281             );
282         }
283     }
284
285     # run type constraints import
286     return Moose::Util::TypeConstraints->import({ into => $callee });
287 }
288
289 =head2 type_export_generator
290
291 Generate a type export, e.g. C<Int()>. This will return either a
292 L<Moose::Meta::TypeConstraint> object, or alternatively a
293 L<MooseX::Types::UndefinedType> object if the type was not
294 yet defined.
295
296 =cut
297
298 sub type_export_generator {
299     my ($class, $type, $full) = @_;
300     return sub { 
301         return find_type_constraint($full)
302             || MooseX::Types::UndefinedType->new($full);
303     };
304 }
305
306 =head2 coercion_export_generator
307
308 This generates a coercion handler function, e.g. C<to_Int($value)>. 
309
310 =cut
311
312 sub coercion_export_generator {
313     my ($class, $type, $full, $undef_msg) = @_;
314     return sub {
315         my ($value) = @_;
316
317         # we need a type object
318         my $tobj = find_type_constraint($full) or croak $undef_msg;
319         my $return = $tobj->coerce($value);
320
321         # non-successful coercion returns false
322         return unless $tobj->check($return);
323
324         return $return;
325     }
326 }
327
328 =head2 check_export_generator
329
330 Generates a constraint check closure, e.g. C<is_Int($value)>.
331
332 =cut
333
334 sub check_export_generator {
335     my ($class, $type, $full, $undef_msg) = @_;
336     return sub {
337         my ($value) = @_;
338
339         # we need a type object
340         my $tobj = find_type_constraint($full) or croak $undef_msg;
341
342         return $tobj->check($value);
343     }
344 }
345
346 =head1 CAVEATS
347
348 A library makes the types quasi-unique by prefixing their names with (by
349 default) the library package name. If you're only using the type handler
350 functions provided by MooseX::Types, you shouldn't ever have to use
351 a type's actual full name.
352
353 =head1 SEE ALSO
354
355 L<Moose>, L<Moose::Util::TypeConstraints>, L<MooseX::Types::Moose>
356
357 =head1 AUTHOR AND COPYRIGHT
358
359 Robert 'phaylon' Sedlacek C<E<lt>rs@474.atE<gt>>, with many thanks to
360 the C<#moose> cabal on C<irc.perl.org>.
361
362 =head1 LICENSE
363
364 This program is free software; you can redistribute it and/or modify
365 it under the same terms as perl itself.
366
367 =cut
368
369 1;