| File | /usr/local/lib/perl5/site_perl/5.10.1/MooseX/Types.pm |
| Statements Executed | 1517 |
| Statement Execution Time | 4.14ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 112 | 7 | 2 | 1.69ms | 43.6ms | MooseX::Types::__ANON__[:486] |
| 1 | 1 | 1 | 1.04ms | 12.2ms | MooseX::Types::BEGIN@12 |
| 1 | 1 | 1 | 755µs | 2.42ms | MooseX::Types::BEGIN@11 |
| 1 | 1 | 1 | 475µs | 1.62ms | MooseX::Types::BEGIN@15 |
| 1 | 1 | 1 | 428µs | 636µs | MooseX::Types::BEGIN@14 |
| 35 | 1 | 1 | 222µs | 303µs | MooseX::Types::type_export_generator |
| 64 | 1 | 1 | 203µs | 1.21ms | MooseX::Types::create_type_decorator |
| 64 | 1 | 1 | 189µs | 1.22ms | MooseX::Types::create_base_type_constraint |
| 2 | 2 | 2 | 169µs | 7.88ms | MooseX::Types::import |
| 35 | 1 | 1 | 155µs | 155µs | MooseX::Types::check_export_generator |
| 30 | 1 | 1 | 109µs | 109µs | MooseX::Types::coercion_export_generator |
| 1 | 1 | 1 | 47µs | 47µs | MooseX::Types::BEGIN@22 |
| 4 | 1 | 1 | 33µs | 2.81ms | MooseX::Types::create_arged_type_constraint |
| 1 | 1 | 1 | 16µs | 2.23ms | MooseX::Types::BEGIN@2 |
| 1 | 1 | 1 | 12µs | 1.20ms | MooseX::Types::BEGIN@10 |
| 1 | 1 | 1 | 10µs | 52µs | MooseX::Types::BEGIN@13 |
| 1 | 1 | 1 | 8µs | 31µs | MooseX::Types::BEGIN@18 |
| 1 | 1 | 1 | 8µs | 31µs | MooseX::Types::BEGIN@17 |
| 1 | 1 | 1 | 8µs | 727µs | MooseX::Types::BEGIN@20 |
| 1 | 1 | 1 | 7µs | 18µs | MooseX::Types::BEGIN@339 |
| 1 | 1 | 1 | 7µs | 78µs | MooseX::Types::BEGIN@16 |
| 10 | 1 | 2 | 3µs | 3µs | MooseX::Types::CORE:match (opcode) |
| 0 | 0 | 0 | 0s | 0s | MooseX::Types::__ANON__[:417] |
| 0 | 0 | 0 | 0s | 0s | MooseX::Types::__ANON__[:504] |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package MooseX::Types; | ||||
| 2 | 3 | 29µs | 2 | 4.44ms | # spent 2.23ms (16µs+2.21) within MooseX::Types::BEGIN@2 which was called
# once (16µs+2.21ms) by SimpleDB::Class::Types::BEGIN@77 at line 2 # spent 2.23ms making 1 call to MooseX::Types::BEGIN@2
# spent 2.21ms making 1 call to Moose::Exporter::__ANON__[Moose/Exporter.pm:389] |
| 3 | |||||
| 4 | =head1 NAME | ||||
| 5 | |||||
| 6 | MooseX::Types - Organise your Moose types in libraries | ||||
| 7 | |||||
| 8 | =cut | ||||
| 9 | |||||
| 10 | 3 | 30µs | 2 | 2.40ms | # spent 1.20ms (12µs+1.19) within MooseX::Types::BEGIN@10 which was called
# once (12µs+1.19ms) by SimpleDB::Class::Types::BEGIN@77 at line 10 # spent 1.20ms making 1 call to MooseX::Types::BEGIN@10
# spent 1.19ms making 1 call to Moose::Exporter::__ANON__[Moose/Exporter.pm:389] |
| 11 | 3 | 123µs | 1 | 2.42ms | # spent 2.42ms (755µs+1.66) within MooseX::Types::BEGIN@11 which was called
# once (755µs+1.66ms) by SimpleDB::Class::Types::BEGIN@77 at line 11 # spent 2.42ms making 1 call to MooseX::Types::BEGIN@11 |
| 12 | 3 | 123µs | 1 | 12.2ms | # spent 12.2ms (1.04+11.1) within MooseX::Types::BEGIN@12 which was called
# once (1.04ms+11.1ms) by SimpleDB::Class::Types::BEGIN@77 at line 12 # spent 12.2ms making 1 call to MooseX::Types::BEGIN@12 |
| 13 | 3 | 24µs | 2 | 93µs | # spent 52µs (10+42) within MooseX::Types::BEGIN@13 which was called
# once (10µs+42µs) by SimpleDB::Class::Types::BEGIN@77 at line 13 # spent 52µs making 1 call to MooseX::Types::BEGIN@13
# spent 42µs making 1 call to Exporter::import |
| 14 | 3 | 142µs | 1 | 636µs | # spent 636µs (428+209) within MooseX::Types::BEGIN@14 which was called
# once (428µs+209µs) by SimpleDB::Class::Types::BEGIN@77 at line 14 # spent 636µs making 1 call to MooseX::Types::BEGIN@14 |
| 15 | 3 | 107µs | 1 | 1.62ms | # spent 1.62ms (475µs+1.15) within MooseX::Types::BEGIN@15 which was called
# once (475µs+1.15ms) by SimpleDB::Class::Types::BEGIN@77 at line 15 # spent 1.62ms making 1 call to MooseX::Types::BEGIN@15 |
| 16 | 3 | 23µs | 2 | 150µs | # spent 78µs (7+71) within MooseX::Types::BEGIN@16 which was called
# once (7µs+71µs) by SimpleDB::Class::Types::BEGIN@77 at line 16 # spent 78µs making 1 call to MooseX::Types::BEGIN@16
# spent 71µs making 1 call to Carp::Clan::import |
| 17 | 3 | 22µs | 2 | 54µs | # spent 31µs (8+23) within MooseX::Types::BEGIN@17 which was called
# once (8µs+23µs) by SimpleDB::Class::Types::BEGIN@77 at line 17 # spent 31µs making 1 call to MooseX::Types::BEGIN@17
# spent 23µs making 1 call to Exporter::import |
| 18 | 3 | 26µs | 2 | 54µs | # spent 31µs (8+23) within MooseX::Types::BEGIN@18 which was called
# once (8µs+23µs) by SimpleDB::Class::Types::BEGIN@77 at line 18 # spent 31µs making 1 call to MooseX::Types::BEGIN@18
# spent 23µs making 1 call to Exporter::import |
| 19 | |||||
| 20 | 3 | 27µs | 2 | 1.45ms | # spent 727µs (8+719) within MooseX::Types::BEGIN@20 which was called
# once (8µs+719µs) by SimpleDB::Class::Types::BEGIN@77 at line 20 # spent 727µs making 1 call to MooseX::Types::BEGIN@20
# spent 719µs making 1 call to namespace::clean::import |
| 21 | |||||
| 22 | 3 | 144µs | 1 | 47µs | # spent 47µs within MooseX::Types::BEGIN@22 which was called
# once (47µs+0s) by SimpleDB::Class::Types::BEGIN@77 at line 22 # spent 47µs making 1 call to MooseX::Types::BEGIN@22 |
| 23 | 1 | 500ns | our $VERSION = '0.20'; | ||
| 24 | 1 | 300ns | my $UndefMsg = q{Action for type '%s' not yet defined in library '%s'}; | ||
| 25 | |||||
| 26 | =head1 SYNOPSIS | ||||
| 27 | |||||
| 28 | =head2 Library Definition | ||||
| 29 | |||||
| 30 | package MyLibrary; | ||||
| 31 | |||||
| 32 | # predeclare our own types | ||||
| 33 | use MooseX::Types | ||||
| 34 | -declare => [qw( | ||||
| 35 | PositiveInt NegativeInt | ||||
| 36 | ArrayRefOfPositiveInt ArrayRefOfAtLeastThreeNegativeInts | ||||
| 37 | LotsOfInnerConstraints StrOrArrayRef | ||||
| 38 | MyDateTime | ||||
| 39 | )]; | ||||
| 40 | |||||
| 41 | # import builtin types | ||||
| 42 | use MooseX::Types::Moose qw/Int HashRef/; | ||||
| 43 | |||||
| 44 | # type definition. | ||||
| 45 | subtype PositiveInt, | ||||
| 46 | as Int, | ||||
| 47 | where { $_ > 0 }, | ||||
| 48 | message { "Int is not larger than 0" }; | ||||
| 49 | |||||
| 50 | subtype NegativeInt, | ||||
| 51 | as Int, | ||||
| 52 | where { $_ < 0 }, | ||||
| 53 | message { "Int is not smaller than 0" }; | ||||
| 54 | |||||
| 55 | # type coercion | ||||
| 56 | coerce PositiveInt, | ||||
| 57 | from Int, | ||||
| 58 | via { 1 }; | ||||
| 59 | |||||
| 60 | # with parameterized constraints. | ||||
| 61 | |||||
| 62 | subtype ArrayRefOfPositiveInt, | ||||
| 63 | as ArrayRef[PositiveInt]; | ||||
| 64 | |||||
| 65 | subtype ArrayRefOfAtLeastThreeNegativeInts, | ||||
| 66 | as ArrayRef[NegativeInt], | ||||
| 67 | where { scalar(@$_) > 2 }; | ||||
| 68 | |||||
| 69 | subtype LotsOfInnerConstraints, | ||||
| 70 | as ArrayRef[ArrayRef[HashRef[Int]]]; | ||||
| 71 | |||||
| 72 | # with TypeConstraint Unions | ||||
| 73 | |||||
| 74 | subtype StrOrArrayRef, | ||||
| 75 | as Str|ArrayRef; | ||||
| 76 | |||||
| 77 | # class types | ||||
| 78 | |||||
| 79 | class_type 'DateTime'; | ||||
| 80 | |||||
| 81 | # or better | ||||
| 82 | |||||
| 83 | class_type MyDateTime, { class => 'DateTime' }; | ||||
| 84 | |||||
| 85 | coerce MyDateTime, | ||||
| 86 | from HashRef, | ||||
| 87 | via { DateTime->new(%$_) }; | ||||
| 88 | |||||
| 89 | 1; | ||||
| 90 | |||||
| 91 | =head2 Usage | ||||
| 92 | |||||
| 93 | package Foo; | ||||
| 94 | use Moose; | ||||
| 95 | use MyLibrary qw( PositiveInt NegativeInt ); | ||||
| 96 | |||||
| 97 | # use the exported constants as type names | ||||
| 98 | has 'bar', | ||||
| 99 | isa => PositiveInt, | ||||
| 100 | is => 'rw'; | ||||
| 101 | has 'baz', | ||||
| 102 | isa => NegativeInt, | ||||
| 103 | is => 'rw'; | ||||
| 104 | |||||
| 105 | sub quux { | ||||
| 106 | my ($self, $value); | ||||
| 107 | |||||
| 108 | # test the value | ||||
| 109 | print "positive\n" if is_PositiveInt($value); | ||||
| 110 | print "negative\n" if is_NegativeInt($value); | ||||
| 111 | |||||
| 112 | # coerce the value, NegativeInt doesn't have a coercion | ||||
| 113 | # helper, since it didn't define any coercions. | ||||
| 114 | $value = to_PositiveInt($value) or die "Cannot coerce"; | ||||
| 115 | } | ||||
| 116 | |||||
| 117 | 1; | ||||
| 118 | |||||
| 119 | =head1 DESCRIPTION | ||||
| 120 | |||||
| 121 | The types provided with L<Moose> are by design global. This package helps | ||||
| 122 | you to organise and selectively import your own and the built-in types in | ||||
| 123 | libraries. As a nice side effect, it catches typos at compile-time too. | ||||
| 124 | |||||
| 125 | However, the main reason for this module is to provide an easy way to not | ||||
| 126 | have conflicts with your type names, since the internal fully qualified | ||||
| 127 | names of the types will be prefixed with the library's name. | ||||
| 128 | |||||
| 129 | This module will also provide you with some helper functions to make it | ||||
| 130 | easier to use Moose types in your code. | ||||
| 131 | |||||
| 132 | String type names will produce a warning, unless it's for a C<class_type> or | ||||
| 133 | C<role_type> declared within the library, or a fully qualified name like | ||||
| 134 | C<'MyTypeLibrary::Foo'>. | ||||
| 135 | |||||
| 136 | =head1 TYPE HANDLER FUNCTIONS | ||||
| 137 | |||||
| 138 | =head2 $type | ||||
| 139 | |||||
| 140 | A constant with the name of your type. It contains the type's fully | ||||
| 141 | qualified name. Takes no value, as all constants. | ||||
| 142 | |||||
| 143 | =head2 is_$type | ||||
| 144 | |||||
| 145 | This handler takes a value and tests if it is a valid value for this | ||||
| 146 | C<$type>. It will return true or false. | ||||
| 147 | |||||
| 148 | =head2 to_$type | ||||
| 149 | |||||
| 150 | A handler that will take a value and coerce it into the C<$type>. It will | ||||
| 151 | return a false value if the type could not be coerced. | ||||
| 152 | |||||
| 153 | B<Important Note>: This handler will only be exported for types that can | ||||
| 154 | do type coercion. This has the advantage that a coercion to a type that | ||||
| 155 | cannot hasn't defined any coercions will lead to a compile-time error. | ||||
| 156 | |||||
| 157 | =head1 LIBRARY DEFINITION | ||||
| 158 | |||||
| 159 | A MooseX::Types is just a normal Perl module. Unlike Moose | ||||
| 160 | itself, it does not install C<use strict> and C<use warnings> in your | ||||
| 161 | class by default, so this is up to you. | ||||
| 162 | |||||
| 163 | The only thing a library is required to do is | ||||
| 164 | |||||
| 165 | use MooseX::Types -declare => \@types; | ||||
| 166 | |||||
| 167 | with C<@types> being a list of types you wish to define in this library. | ||||
| 168 | This line will install a proper base class in your package as well as the | ||||
| 169 | full set of L<handlers|/"TYPE HANDLER FUNCTIONS"> for your declared | ||||
| 170 | types. It will then hand control over to L<Moose::Util::TypeConstraints>' | ||||
| 171 | C<import> method to export the functions you will need to declare your | ||||
| 172 | types. | ||||
| 173 | |||||
| 174 | If you want to use Moose' built-in types (e.g. for subtyping) you will | ||||
| 175 | want to | ||||
| 176 | |||||
| 177 | use MooseX::Types::Moose @types; | ||||
| 178 | |||||
| 179 | to import the helpers from the shipped L<MooseX::Types::Moose> | ||||
| 180 | library which can export all types that come with Moose. | ||||
| 181 | |||||
| 182 | You will have to define coercions for your types or your library won't | ||||
| 183 | export a L</to_$type> coercion helper for it. | ||||
| 184 | |||||
| 185 | Note that you currently cannot define types containing C<::>, since | ||||
| 186 | exporting would be a problem. | ||||
| 187 | |||||
| 188 | You also don't need to use C<warnings> and C<strict>, since the | ||||
| 189 | definition of a library automatically exports those. | ||||
| 190 | |||||
| 191 | =head1 LIBRARY USAGE | ||||
| 192 | |||||
| 193 | You can import the L<"type helpers"|/"TYPE HANDLER FUNCTIONS"> of a | ||||
| 194 | library by C<use>ing it with a list of types to import as arguments. If | ||||
| 195 | you want all of them, use the C<:all> tag. For example: | ||||
| 196 | |||||
| 197 | use MyLibrary ':all'; | ||||
| 198 | use MyOtherLibrary qw( TypeA TypeB ); | ||||
| 199 | |||||
| 200 | MooseX::Types comes with a library of Moose' built-in types called | ||||
| 201 | L<MooseX::Types::Moose>. | ||||
| 202 | |||||
| 203 | The exporting mechanism is, since version 0.5, implemented via a wrapper | ||||
| 204 | around L<Sub::Exporter>. This means you can do something like this: | ||||
| 205 | |||||
| 206 | use MyLibrary TypeA => { -as => 'MyTypeA' }, | ||||
| 207 | TypeB => { -as => 'MyTypeB' }; | ||||
| 208 | |||||
| 209 | =head1 WRAPPING A LIBRARY | ||||
| 210 | |||||
| 211 | You can define your own wrapper subclasses to manipulate the behaviour | ||||
| 212 | of a set of library exports. Here is an example: | ||||
| 213 | |||||
| 214 | package MyWrapper; | ||||
| 215 | use strict; | ||||
| 216 | use Class::C3; | ||||
| 217 | use base 'MooseX::Types::Wrapper'; | ||||
| 218 | |||||
| 219 | sub coercion_export_generator { | ||||
| 220 | my $class = shift; | ||||
| 221 | my $code = $class->next::method(@_); | ||||
| 222 | return sub { | ||||
| 223 | my $value = $code->(@_); | ||||
| 224 | warn "Coercion returned undef!" | ||||
| 225 | unless defined $value; | ||||
| 226 | return $value; | ||||
| 227 | }; | ||||
| 228 | } | ||||
| 229 | |||||
| 230 | 1; | ||||
| 231 | |||||
| 232 | This class wraps the coercion generator (e.g., C<to_Int()>) and warns | ||||
| 233 | if a coercion returned an undefined value. You can wrap any library | ||||
| 234 | with this: | ||||
| 235 | |||||
| 236 | package Foo; | ||||
| 237 | use strict; | ||||
| 238 | use MyWrapper MyLibrary => [qw( Foo Bar )], | ||||
| 239 | Moose => [qw( Str Int )]; | ||||
| 240 | |||||
| 241 | ... | ||||
| 242 | 1; | ||||
| 243 | |||||
| 244 | The C<Moose> library name is a special shortcut for | ||||
| 245 | L<MooseX::Types::Moose>. | ||||
| 246 | |||||
| 247 | =head2 Generator methods you can overload | ||||
| 248 | |||||
| 249 | =over 4 | ||||
| 250 | |||||
| 251 | =item type_export_generator( $short, $full ) | ||||
| 252 | |||||
| 253 | Creates a closure returning the type's L<Moose::Meta::TypeConstraint> | ||||
| 254 | object. | ||||
| 255 | |||||
| 256 | =item check_export_generator( $short, $full, $undef_message ) | ||||
| 257 | |||||
| 258 | This creates the closure used to test if a value is valid for this type. | ||||
| 259 | |||||
| 260 | =item coercion_export_generator( $short, $full, $undef_message ) | ||||
| 261 | |||||
| 262 | This is the closure that's doing coercions. | ||||
| 263 | |||||
| 264 | =back | ||||
| 265 | |||||
| 266 | =head2 Provided Parameters | ||||
| 267 | |||||
| 268 | =over 4 | ||||
| 269 | |||||
| 270 | =item $short | ||||
| 271 | |||||
| 272 | The short, exported name of the type. | ||||
| 273 | |||||
| 274 | =item $full | ||||
| 275 | |||||
| 276 | The fully qualified name of this type as L<Moose> knows it. | ||||
| 277 | |||||
| 278 | =item $undef_message | ||||
| 279 | |||||
| 280 | A message that will be thrown when type functionality is used but the | ||||
| 281 | type does not yet exist. | ||||
| 282 | |||||
| 283 | =back | ||||
| 284 | |||||
| 285 | =head1 RECURSIVE SUBTYPES | ||||
| 286 | |||||
| 287 | As of version 0.08, L<Moose::Types> has experimental support for Recursive | ||||
| 288 | subtypes. This will allow: | ||||
| 289 | |||||
| 290 | subtype Tree() => as HashRef[Str|Tree]; | ||||
| 291 | |||||
| 292 | Which validates things like: | ||||
| 293 | |||||
| 294 | {key=>'value'}; | ||||
| 295 | {key=>{subkey1=>'value', subkey2=>'value'}} | ||||
| 296 | |||||
| 297 | And so on. This feature is new and there may be lurking bugs so don't be afraid | ||||
| 298 | to hunt me down with patches and test cases if you have trouble. | ||||
| 299 | |||||
| 300 | =head1 NOTES REGARDING TYPE UNIONS | ||||
| 301 | |||||
| 302 | L<MooseX::Types> uses L<MooseX::Types::TypeDecorator> to do some overloading | ||||
| 303 | which generally allows you to easily create union types: | ||||
| 304 | |||||
| 305 | subtype StrOrArrayRef, | ||||
| 306 | as Str|ArrayRef; | ||||
| 307 | |||||
| 308 | As with parameterized constrains, this overloading extends to modules using the | ||||
| 309 | types you define in a type library. | ||||
| 310 | |||||
| 311 | use Moose; | ||||
| 312 | use MooseX::Types::Moose qw(HashRef Int); | ||||
| 313 | |||||
| 314 | has 'attr' => (isa=>HashRef|Int); | ||||
| 315 | |||||
| 316 | And everything should just work as you'd think. | ||||
| 317 | |||||
| 318 | =head1 METHODS | ||||
| 319 | |||||
| 320 | =head2 import | ||||
| 321 | |||||
| 322 | Installs the L<MooseX::Types::Base> class into the caller and | ||||
| 323 | exports types according to the specification described in | ||||
| 324 | L</"LIBRARY DEFINITION">. This will continue to | ||||
| 325 | L<Moose::Util::TypeConstraints>' C<import> method to export helper | ||||
| 326 | functions you will need to declare your types. | ||||
| 327 | |||||
| 328 | =cut | ||||
| 329 | |||||
| 330 | # spent 7.88ms (169µs+7.71) within MooseX::Types::import which was called 2 times, avg 3.94ms/call:
# once (141µs+5.52ms) by SimpleDB::Class::Types::BEGIN@77 at line 77 of ../lib/SimpleDB/Class/Types.pm
# once (27µs+2.19ms) by MooseX::Types::Moose::BEGIN@12 at line 12 of MooseX/Types/Moose.pm | ||||
| 331 | 54 | 140µs | my ($class, %args) = @_; | ||
| 332 | my $callee = caller; | ||||
| 333 | |||||
| 334 | # everyone should want this | ||||
| 335 | strict->import; # spent 4µs making 2 calls to strict::import, avg 2µs/call | ||||
| 336 | warnings->import; # spent 18µs making 2 calls to warnings::import, avg 9µs/call | ||||
| 337 | |||||
| 338 | # inject base class into new library | ||||
| 339 | 3 | 555µs | 2 | 28µs | # spent 18µs (7+11) within MooseX::Types::BEGIN@339 which was called
# once (7µs+11µs) by SimpleDB::Class::Types::BEGIN@77 at line 339 # spent 18µs making 1 call to MooseX::Types::BEGIN@339
# spent 11µs making 1 call to strict::unimport |
| 340 | unshift @{ $callee . '::ISA' }, 'MooseX::Types::Base'; | ||||
| 341 | } | ||||
| 342 | |||||
| 343 | # generate predeclared type helpers | ||||
| 344 | if (my @orig_declare = @{ $args{ -declare } || [] }) { | ||||
| 345 | my ($tags, $declare) = filter_tags @orig_declare; # spent 35µs making 1 call to MooseX::Types::Util::filter_tags | ||||
| 346 | my @to_export; | ||||
| 347 | |||||
| 348 | for my $type (@$declare) { | ||||
| 349 | |||||
| 350 | croak "Cannot create a type containing '::' ($type) at the moment" # spent 3µs making 10 calls to MooseX::Types::CORE:match, avg 260ns/call | ||||
| 351 | if $type =~ /::/; | ||||
| 352 | |||||
| 353 | # add type to library and remember to export | ||||
| 354 | $callee->add_type($type); # spent 64µs making 10 calls to MooseX::Types::Base::add_type, avg 6µs/call | ||||
| 355 | push @to_export, $type; | ||||
| 356 | } | ||||
| 357 | |||||
| 358 | $callee->import({ -full => 1, -into => $callee }, @to_export); # spent 3.10ms making 1 call to MooseX::Types::Base::import | ||||
| 359 | } | ||||
| 360 | |||||
| 361 | # run type constraints import | ||||
| 362 | Moose::Util::TypeConstraints->import({ into => $callee }); # spent 2.39ms making 2 calls to Moose::Exporter::__ANON__[Moose/Exporter.pm:389], avg 1.20ms/call | ||||
| 363 | |||||
| 364 | # override some with versions that check for syntax errors | ||||
| 365 | MooseX::Types::CheckedUtilExports->import({ into => $callee }); # spent 2.09ms making 2 calls to Moose::Exporter::__ANON__[Moose/Exporter.pm:389], avg 1.04ms/call | ||||
| 366 | |||||
| 367 | 1; | ||||
| 368 | } | ||||
| 369 | |||||
| 370 | =head2 type_export_generator | ||||
| 371 | |||||
| 372 | Generate a type export, e.g. C<Int()>. This will return either a | ||||
| 373 | L<Moose::Meta::TypeConstraint> object, or alternatively a | ||||
| 374 | L<MooseX::Types::UndefinedType> object if the type was not | ||||
| 375 | yet defined. | ||||
| 376 | |||||
| 377 | =cut | ||||
| 378 | |||||
| 379 | # spent 303µs (222+81) within MooseX::Types::type_export_generator which was called 35 times, avg 9µs/call:
# 35 times (222µs+81µs) by MooseX::Types::Base::__ANON__[/usr/local/lib/perl5/site_perl/5.10.1/MooseX/Types/Base.pm:72] at line 70 of MooseX/Types/Base.pm, avg 9µs/call | ||||
| 380 | 70 | 331µs | my ($class, $type, $name) = @_; | ||
| 381 | |||||
| 382 | ## Return an anonymous subroutine that will generate the proxied type | ||||
| 383 | ## constraint for you. | ||||
| 384 | |||||
| 385 | return subname "__TYPE__::$name" => sub { | ||||
| 386 | 388 | 421µs | 64 | 1.22ms | my $type_constraint = $class->create_base_type_constraint($name); # spent 1.22ms making 64 calls to MooseX::Types::create_base_type_constraint, avg 19µs/call |
| 387 | |||||
| 388 | if(defined(my $params = shift @_)) { | ||||
| 389 | ## We currently only allow a TC to accept a single, ArrayRef | ||||
| 390 | ## parameter, as in HashRef[Int], where [Int] is what's inside the | ||||
| 391 | ## ArrayRef passed. | ||||
| 392 | if(reftype $params eq 'ARRAY') { # spent 2.81ms making 4 calls to MooseX::Types::create_arged_type_constraint, avg 703µs/call
# spent 3µs making 4 calls to Scalar::Util::reftype, avg 725ns/call | ||||
| 393 | $type_constraint = $class->create_arged_type_constraint($name, @$params); | ||||
| 394 | } elsif(!defined $type_constraint) { | ||||
| 395 | croak "Syntax error in type definition (did you forget a comma" | ||||
| 396 | . " after $type?)"; | ||||
| 397 | } else { | ||||
| 398 | croak "Argument must be an ArrayRef to create a parameterized " | ||||
| 399 | . "type, Eg.: ${type}[Int]. Got: ".ref($params)."." | ||||
| 400 | } | ||||
| 401 | } | ||||
| 402 | |||||
| 403 | $type_constraint = defined($type_constraint) ? $type_constraint # spent 52µs making 10 calls to MooseX::Types::UndefinedType::new, avg 5µs/call | ||||
| 404 | : MooseX::Types::UndefinedType->new($name); | ||||
| 405 | |||||
| 406 | my $type_decorator = $class->create_type_decorator($type_constraint); # spent 1.21ms making 64 calls to MooseX::Types::create_type_decorator, avg 19µs/call | ||||
| 407 | |||||
| 408 | ## If there are additional args, that means it's probably stuff that | ||||
| 409 | ## needs to be returned to the subtype. Not an ideal solution here but | ||||
| 410 | ## doesn't seem to cause trouble. | ||||
| 411 | |||||
| 412 | if(@_) { | ||||
| 413 | return ($type_decorator, @_); | ||||
| 414 | } else { | ||||
| 415 | return $type_decorator; | ||||
| 416 | } | ||||
| 417 | }; # spent 81µs making 35 calls to Sub::Name::subname, avg 2µs/call | ||||
| 418 | } | ||||
| 419 | |||||
| 420 | =head2 create_arged_type_constraint ($name, @args) | ||||
| 421 | |||||
| 422 | Given a String $name with @args find the matching typeconstraint and parameterize | ||||
| 423 | it with @args. | ||||
| 424 | |||||
| 425 | =cut | ||||
| 426 | |||||
| 427 | # spent 2.81ms (33µs+2.78) within MooseX::Types::create_arged_type_constraint which was called 4 times, avg 703µs/call:
# 4 times (33µs+2.78ms) by __TYPE__::ArrayRef at line 392, avg 703µs/call | ||||
| 428 | 16 | 27µs | my ($class, $name, @args) = @_; | ||
| 429 | my $type_constraint = Moose::Util::TypeConstraints::find_or_create_type_constraint("$name"); # spent 167µs making 4 calls to Moose::Util::TypeConstraints::find_or_create_type_constraint, avg 42µs/call | ||||
| 430 | my $parameterized = $type_constraint->parameterize(@args); # spent 2.61ms making 4 calls to Moose::Meta::TypeConstraint::Parameterizable::parameterize, avg 653µs/call | ||||
| 431 | # It's obnoxious to have to parameterize before looking for the TC, but the | ||||
| 432 | # alternative is to hard-code the assumption that the name is | ||||
| 433 | # "$name[$args[0]]", which would be worse. | ||||
| 434 | # This breaks MXMS, unfortunately, which relies on things like Tuple[...] | ||||
| 435 | # creating new type objects each time. | ||||
| 436 | # if (my $existing = | ||||
| 437 | # Moose::Util::TypeConstraints::find_type_constraint($parameterized->name)) { | ||||
| 438 | # return $existing; | ||||
| 439 | # } | ||||
| 440 | # Moose::Util::TypeConstraints::register_type_constraint($parameterized); | ||||
| 441 | return $parameterized; | ||||
| 442 | } | ||||
| 443 | |||||
| 444 | =head2 create_base_type_constraint ($name) | ||||
| 445 | |||||
| 446 | Given a String $name, find the matching typeconstraint. | ||||
| 447 | |||||
| 448 | =cut | ||||
| 449 | |||||
| 450 | # spent 1.22ms (189µs+1.03) within MooseX::Types::create_base_type_constraint which was called 64 times, avg 19µs/call:
# 64 times (189µs+1.03ms) by __TYPE__::ArrayRef or __TYPE__::HashRef or __TYPE__::Int or __TYPE__::SimpleDB::Class::Types::SdbArrayRefOfDateTime or __TYPE__::SimpleDB::Class::Types::SdbArrayRefOfInt or __TYPE__::SimpleDB::Class::Types::SdbArrayRefOfIntAsStr or __TYPE__::SimpleDB::Class::Types::SdbArrayRefOfStr or __TYPE__::SimpleDB::Class::Types::SdbDateTime or __TYPE__::SimpleDB::Class::Types::SdbHashRef or __TYPE__::SimpleDB::Class::Types::SdbInt or __TYPE__::SimpleDB::Class::Types::SdbIntAsStr or __TYPE__::SimpleDB::Class::Types::SdbMediumStr or __TYPE__::SimpleDB::Class::Types::SdbStr or __TYPE__::Str or __TYPE__::Undef at line 386, avg 19µs/call | ||||
| 451 | 128 | 187µs | my ($class, $name) = @_; | ||
| 452 | return find_type_constraint($name); # spent 1.03ms making 64 calls to Moose::Util::TypeConstraints::find_type_constraint, avg 16µs/call | ||||
| 453 | } | ||||
| 454 | |||||
| 455 | =head2 create_type_decorator ($type_constraint) | ||||
| 456 | |||||
| 457 | Given a $type_constraint, return a lightweight L<MooseX::Types::TypeDecorator> | ||||
| 458 | instance. | ||||
| 459 | |||||
| 460 | =cut | ||||
| 461 | |||||
| 462 | # spent 1.21ms (203µs+1.01) within MooseX::Types::create_type_decorator which was called 64 times, avg 19µs/call:
# 64 times (203µs+1.01ms) by __TYPE__::ArrayRef or __TYPE__::HashRef or __TYPE__::Int or __TYPE__::SimpleDB::Class::Types::SdbArrayRefOfDateTime or __TYPE__::SimpleDB::Class::Types::SdbArrayRefOfInt or __TYPE__::SimpleDB::Class::Types::SdbArrayRefOfIntAsStr or __TYPE__::SimpleDB::Class::Types::SdbArrayRefOfStr or __TYPE__::SimpleDB::Class::Types::SdbDateTime or __TYPE__::SimpleDB::Class::Types::SdbHashRef or __TYPE__::SimpleDB::Class::Types::SdbInt or __TYPE__::SimpleDB::Class::Types::SdbIntAsStr or __TYPE__::SimpleDB::Class::Types::SdbMediumStr or __TYPE__::SimpleDB::Class::Types::SdbStr or __TYPE__::Str or __TYPE__::Undef at line 406, avg 19µs/call | ||||
| 463 | 128 | 195µs | my ($class, $type_constraint) = @_; | ||
| 464 | return MooseX::Types::TypeDecorator->new($type_constraint); # spent 1.01ms making 64 calls to MooseX::Types::TypeDecorator::new, avg 16µs/call | ||||
| 465 | } | ||||
| 466 | |||||
| 467 | =head2 coercion_export_generator | ||||
| 468 | |||||
| 469 | This generates a coercion handler function, e.g. C<to_Int($value)>. | ||||
| 470 | |||||
| 471 | =cut | ||||
| 472 | |||||
| 473 | # spent 109µs within MooseX::Types::coercion_export_generator which was called 30 times, avg 4µs/call:
# 30 times (109µs+0s) by MooseX::Types::Base::__ANON__[/usr/local/lib/perl5/site_perl/5.10.1/MooseX/Types/Base.pm:85] at line 85 of MooseX/Types/Base.pm, avg 4µs/call | ||||
| 474 | 60 | 139µs | my ($class, $type, $full, $undef_msg) = @_; | ||
| 475 | # spent 43.6ms (1.69+41.9) within MooseX::Types::__ANON__[/usr/local/lib/perl5/site_perl/5.10.1/MooseX/Types.pm:486] which was called 112 times, avg 389µs/call:
# 47 times (628µs+5.11ms) by SimpleDB::Class::Item::stringify_values at line 633 of ../lib/SimpleDB/Class/Item.pm, avg 122µs/call
# 32 times (484µs+4.61ms) by SimpleDB::Class::Item::stringify_values at line 623 of ../lib/SimpleDB/Class/Item.pm, avg 159µs/call
# 12 times (203µs+931µs) by SimpleDB::Class::Item::stringify_value at line 588 of ../lib/SimpleDB/Class/Item.pm, avg 95µs/call
# 6 times (137µs+1.12ms) by SimpleDB::Class::Item::stringify_value at line 584 of ../lib/SimpleDB/Class/Item.pm, avg 209µs/call
# 5 times (73µs+28.7ms) by SimpleDB::Class::Types::__ANON__[../lib/SimpleDB/Class/Types.pm:186] at line 186 of ../lib/SimpleDB/Class/Types.pm, avg 5.75ms/call
# 5 times (98µs+917µs) by SimpleDB::Class::Types::__ANON__[../lib/SimpleDB/Class/Types.pm:221] at line 213 of ../lib/SimpleDB/Class/Types.pm, avg 203µs/call
# 5 times (65µs+559µs) by SimpleDB::Class::Types::__ANON__[../lib/SimpleDB/Class/Types.pm:206] at line 206 of ../lib/SimpleDB/Class/Types.pm, avg 125µs/call | ||||
| 476 | 560 | 1.07ms | my ($value) = @_; | ||
| 477 | |||||
| 478 | # we need a type object | ||||
| 479 | 1 | 50µs | 224 | 3.44ms | my $tobj = find_type_constraint($full) or croak $undef_msg; # spent 2.83ms making 112 calls to Moose::Util::TypeConstraints::find_type_constraint, avg 25µs/call
# spent 606µs making 112 calls to Moose::Meta::TypeConstraint::__ANON__[Moose/Meta/TypeConstraint.pm:8], avg 5µs/call |
| 480 | my $return = $tobj->coerce($value); # spent 36.1ms making 112 calls to Moose::Meta::TypeConstraint::coerce, avg 322µs/call, recursion: max depth 1, time 29.3ms | ||||
| 481 | |||||
| 482 | # non-successful coercion returns false | ||||
| 483 | return unless $tobj->check($return); # spent 2.36ms making 112 calls to Moose::Meta::TypeConstraint::check, avg 21µs/call | ||||
| 484 | |||||
| 485 | return $return; | ||||
| 486 | } | ||||
| 487 | } | ||||
| 488 | |||||
| 489 | =head2 check_export_generator | ||||
| 490 | |||||
| 491 | Generates a constraint check closure, e.g. C<is_Int($value)>. | ||||
| 492 | |||||
| 493 | =cut | ||||
| 494 | |||||
| 495 | # spent 155µs within MooseX::Types::check_export_generator which was called 35 times, avg 4µs/call:
# 35 times (155µs+0s) by MooseX::Types::Base::__ANON__[/usr/local/lib/perl5/site_perl/5.10.1/MooseX/Types/Base.pm:77] at line 77 of MooseX/Types/Base.pm, avg 4µs/call | ||||
| 496 | 70 | 193µs | my ($class, $type, $full, $undef_msg) = @_; | ||
| 497 | return sub { | ||||
| 498 | my ($value) = @_; | ||||
| 499 | |||||
| 500 | # we need a type object | ||||
| 501 | my $tobj = find_type_constraint($full) or croak $undef_msg; | ||||
| 502 | |||||
| 503 | return $tobj->check($value); | ||||
| 504 | } | ||||
| 505 | } | ||||
| 506 | |||||
| 507 | =head1 CAVEATS | ||||
| 508 | |||||
| 509 | The following are lists of gotcha's and their workarounds for developers coming | ||||
| 510 | from the standard string based type constraint names | ||||
| 511 | |||||
| 512 | =head2 Uniqueness | ||||
| 513 | |||||
| 514 | A library makes the types quasi-unique by prefixing their names with (by | ||||
| 515 | default) the library package name. If you're only using the type handler | ||||
| 516 | functions provided by MooseX::Types, you shouldn't ever have to use | ||||
| 517 | a type's actual full name. | ||||
| 518 | |||||
| 519 | =head2 Argument separation ('=>' versus ',') | ||||
| 520 | |||||
| 521 | The Perlop manpage has this to say about the '=>' operator: "The => operator is | ||||
| 522 | a synonym for the comma, but forces any word (consisting entirely of word | ||||
| 523 | characters) to its left to be interpreted as a string (as of 5.001). This | ||||
| 524 | includes words that might otherwise be considered a constant or function call." | ||||
| 525 | |||||
| 526 | Due to this stringification, the following will NOT work as you might think: | ||||
| 527 | |||||
| 528 | subtype StrOrArrayRef => as Str|ArrayRef; | ||||
| 529 | |||||
| 530 | The 'StrOrArrayRef' will have it's stringification activated this causes the | ||||
| 531 | subtype to not be created. Since the bareword type constraints are not strings | ||||
| 532 | you really should not try to treat them that way. You will have to use the ',' | ||||
| 533 | operator instead. The author's of this package realize that all the L<Moose> | ||||
| 534 | documention and examples nearly uniformly use the '=>' version of the comma | ||||
| 535 | operator and this could be an issue if you are converting code. | ||||
| 536 | |||||
| 537 | Patches welcome for discussion. | ||||
| 538 | |||||
| 539 | =head2 Compatibility with Sub::Exporter | ||||
| 540 | |||||
| 541 | If you want to use L<Sub::Exporter> with a Type Library, you need to make sure | ||||
| 542 | you export all the type constraints declared AS WELL AS any additional export | ||||
| 543 | targets. For example if you do: | ||||
| 544 | |||||
| 545 | package TypeAndSubExporter; { | ||||
| 546 | |||||
| 547 | use MooseX::Types::Moose qw(Str); | ||||
| 548 | use MooseX::Types -declare => [qw(MyStr)]; | ||||
| 549 | use Sub::Exporter -setup => { exports => [ qw(something) ] }; | ||||
| 550 | |||||
| 551 | subtype MyStr, | ||||
| 552 | as Str; | ||||
| 553 | |||||
| 554 | sub something { | ||||
| 555 | return 1; | ||||
| 556 | } | ||||
| 557 | |||||
| 558 | } 1; | ||||
| 559 | |||||
| 560 | package Foo; { | ||||
| 561 | use TypeAndSubExporter qw(MyStr); | ||||
| 562 | } 1; | ||||
| 563 | |||||
| 564 | You'll get a '"MyStr" is not exported by the TypeAndSubExporter module' error. | ||||
| 565 | Upi can workaround by: | ||||
| 566 | |||||
| 567 | - use Sub::Exporter -setup => { exports => [ qw(something) ] }; | ||||
| 568 | + use Sub::Exporter -setup => { exports => [ qw(something MyStr) ] }; | ||||
| 569 | |||||
| 570 | This is a workaround and I am exploring how to make these modules work better | ||||
| 571 | together. I realize this workaround will lead a lot of duplication in your | ||||
| 572 | export declarations and will be onerous for large type libraries. Patches and | ||||
| 573 | detailed test cases welcome. See the tests directory for a start on this. | ||||
| 574 | |||||
| 575 | =head1 SEE ALSO | ||||
| 576 | |||||
| 577 | L<Moose>, | ||||
| 578 | L<Moose::Util::TypeConstraints>, | ||||
| 579 | L<MooseX::Types::Moose>, | ||||
| 580 | L<Sub::Exporter> | ||||
| 581 | |||||
| 582 | =head1 ACKNOWLEDGEMENTS | ||||
| 583 | |||||
| 584 | Many thanks to the C<#moose> cabal on C<irc.perl.org>. | ||||
| 585 | |||||
| 586 | =head1 AUTHOR | ||||
| 587 | |||||
| 588 | Robert "phaylon" Sedlacek <rs@474.at> | ||||
| 589 | |||||
| 590 | =head1 CONTRIBUTORS | ||||
| 591 | |||||
| 592 | jnapiorkowski: John Napiorkowski <jjnapiork@cpan.org> | ||||
| 593 | |||||
| 594 | caelum: Rafael Kitover <rkitover@cpan.org> | ||||
| 595 | |||||
| 596 | rafl: Florian Ragwitz <rafl@debian.org> | ||||
| 597 | |||||
| 598 | hdp: Hans Dieter Pearcey <hdp@cpan.org> | ||||
| 599 | |||||
| 600 | =head1 COPYRIGHT & LICENSE | ||||
| 601 | |||||
| 602 | Copyright (c) 2007-2009 Robert Sedlacek <rs@474.at> | ||||
| 603 | |||||
| 604 | This program is free software; you can redistribute it and/or modify | ||||
| 605 | it under the same terms as perl itself. | ||||
| 606 | |||||
| 607 | =cut | ||||
| 608 | |||||
| 609 | 1 | 14µs | 1 | 622µs | 1; # spent 622µs making 1 call to B::Hooks::EndOfScope::__ANON__[B/Hooks/EndOfScope.pm:47] |
# spent 3µs within MooseX::Types::CORE:match which was called 10 times, avg 260ns/call:
# 10 times (3µs+0s) by MooseX::Types::import at line 350 of MooseX/Types.pm, avg 260ns/call |