1Type::Tiny::Manual::UsiUnsgeWritChoMnotor(i3b)uted PerlTDyopceu:m:eTnitnayt:i:oMnanual::UsingWithMoo(3)
2
3
4
6 Type::Tiny::Manual::UsingWithMoo - basic use of Type::Tiny with Moo
7
9 Type Constraints
10 Consider the following basic Moo class:
11
12 package Horse {
13 use Moo;
14 use namespace::autoclean;
15
16 has name => ( is => 'ro' );
17 has gender => ( is => 'ro' );
18 has age => ( is => 'rw' );
19 has children => ( is => 'ro', default => sub { [] } );
20 }
21
22 Code like this seems simple enough:
23
24 my $br = Horse->new(name => "Bold Ruler", gender => 'm', age => 16);
25 push @{ $br->children },
26 Horse->new(name => 'Secretariat', gender => 'm', age => 0);
27
28 However, once you step away from very simple use of the class, things
29 can start to go wrong. When we push a new horse onto "@{ $br->children
30 }", we are assuming that "$br->children" returned an arrayref.
31
32 What if the code that created the $br horse had instantiated it like
33 this?
34
35 my $br = Horse->new(name => "Bold Ruler", children => 'no');
36
37 It is for this reason that it's useful for the Horse class to perform
38 some basic sanity-checking on its own attributes.
39
40 package Horse {
41 use Moo;
42 use Types::Standard qw( Str Num ArrayRef );
43 use namespace::autoclean;
44
45 has name => ( is => 'ro', isa => Str );
46 has gender => ( is => 'ro', isa => Str );
47 has age => ( is => 'rw', isa => Num );
48 has children => (
49 is => 'ro',
50 isa => ArrayRef,
51 default => sub { return [] },
52 );
53 }
54
55 Now, if you instantiate a horse like this, it will throw an error:
56
57 my $br = Horse->new(name => "Bold Ruler", children => 'no');
58
59 The first type constraint we used here was Str. This is type constraint
60 that requires values to be strings.
61
62 Note that although "undef" is not a string, the empty string is still a
63 string and you will often want to check that a string is non-empty. We
64 could have done this:
65
66 use Types::Common::String qw( NonEmptyStr );
67 has name => ( is => 'ro', isa => NonEmptyStr );
68
69 While most of the type constraints we will use in this manual are
70 defined in Types::Standard, the Types::Common::String type library also
71 defines many useful type constraints.
72
73 We have required the horse's age to be a number. This is also a common,
74 useful type constraint. If we want to make sure it's a whole number, we
75 could use:
76
77 use Types::Standard qw( Int );
78 has age => ( is => 'rw', isa => Int );
79
80 Or because negative numbers make little sense as an age:
81
82 use Types::Common::Numeric qw( PositiveOrZeroInt );
83 has age => ( is => 'rw', isa => PositiveOrZeroInt );
84
85 The Types::Common::Numeric library defines many useful subtypes of Int
86 and Num, such as PositiveInt and PositiveOrZeroInt.
87
88 The last type constraint we've used in this example is ArrayRef. This
89 requires the value to be a reference to an array.
90
91 Types::Standard also provides HashRef and CodeRef type constraints. An
92 example of using the latter:
93
94 package Task {
95 use Moo;
96 use Types::Standard qw( CodeRef Bool );
97 has on_success => ( is => 'ro', isa => CodeRef );
98 has on_failure => ( is => 'ro', isa => CodeRef );
99 has finished => ( is => 'ro', isa => Bool, default => 0 );
100 ...;
101 }
102
103 my $task = Task->new(
104 on_success => sub { ... },
105 on_failure => sub { ... },
106 ...,
107 );
108
109 The Bool type constraint accepts "1" as a true value, and "0", "", or
110 undef as false values. No other values are accepted.
111
112 There exists an Object type constraint that accepts any blessed object.
113
114 package Horse {
115 use Moo;
116 use Types::Standard qw( Object );
117 use namespace::autoclean;
118
119 ...; # name, gender, age, children
120 has father => ( is => 'ro', isa => Object );
121 has mother => ( is => 'ro', isa => Object );
122 }
123
124 Finally, another useful type constraint to know about is Any:
125
126 use Types::Standard qw( Any );
127 has stuff => ( is => 'rw', isa => Any );
128
129 This type constraint allows any value; it is essentially the same as
130 not doing any type check, but makes your intent clearer. Where
131 possible, Type::Tiny will optimize away this type check, so it should
132 have little (if any) impact on performance.
133
134 Parameterized Types
135 Let's imagine we want to keep track of our horse's race wins:
136
137 package Horse {
138 use Moo;
139 use Types::Standard qw( Str Num ArrayRef );
140 use namespace::autoclean;
141
142 ...; # name, gender, age, children
143 has wins => (
144 is => 'ro',
145 isa => ArrayRef,
146 default => sub { return [] },
147 );
148 }
149
150 We can create a horse like this:
151
152 my $br = Horse->new(
153 name => "Bold Ruler",
154 gender => 'm',
155 age => 4,
156 wins => ["Futurity Stakes 1956", "Juvenile Stakes 1956"],
157 );
158
159 The list of wins is an arrayref of strings. The ArrayRef type
160 constraint prevents it from being set to a hashref, for example, but it
161 doesn't ensure that everything in the arrayref is a string. To do that,
162 we need to parameterize the type constraint:
163
164 has wins => (
165 is => 'ro',
166 isa => ArrayRef[Str],
167 default => sub { return [] },
168 );
169
170 Thanks to the ArrayRef[Str] parameterized type, the constructor will
171 throw an error if the arrayref you pass to it contains anything non-
172 string.
173
174 An alternative way of writing this is:
175
176 has wins => (
177 is => 'ro',
178 isa => ArrayRef->of(Str),
179 default => sub { return [] },
180 );
181
182 Which way you choose is largely a style preference. TIMTOWTDI!
183
184 Note that although the constructor and any setter/accessor method will
185 perform type checks, it is possible to bypass them using:
186
187 push @{ $br->wins }, $not_a_string;
188
189 The constructor isn't being called here, and although the accessor is
190 being called, it's being called as a reader, not a writer, so never
191 gets an opportunity to inspect the value being added. (It is possible
192 to use "tie" to solve this, but that will be covered later.)
193
194 And of course, if you directly poke at the underlying hashref of the
195 object, all bets are off:
196
197 $br->{wins} = $not_an_arrayref;
198
199 So type constraints do have limitations. Careful API design (and not
200 circumventing the proper API) can help.
201
202 The HashRef type constraint can also be parameterized:
203
204 package Design {
205 use Moo;
206 use Types::Standard qw( HashRef Str );
207 has colours => ( is => 'ro', isa => HashRef[Str] );
208 }
209
210 my $eiffel65 = Design->new(
211 colours => { house => "blue", little_window => "blue" },
212 );
213
214 The HashRef[Str] type constraint ensures the values of the hashref are
215 strings; it doesn't check the keys of the hashref because keys in Perl
216 hashes are always strings!
217
218 If you do need to constrain the keys, it is possible to use a
219 parameterized Map constraint:
220
221 use Types::Common::String qw( NonEmptyStr );
222 use Types::Standard qw( Map );
223 has colours => ( is => 'ro', isa => Map[NonEmptyStr, NonEmptyStr] );
224
225 Map takes two parameters; the first is a type to check keys against and
226 the second is a type to check values against.
227
228 Another useful type constraint is the Tuple type constraint.
229
230 use Types::Standard qw( ArrayRef Tuple );
231 use Types::Common::Numeric qw( PositiveInt );
232 use Types::Common::String qw( NonEmptyStr );
233
234 has wins => (
235 is => 'ro',
236 isa => ArrayRef[ Tuple[PositiveInt, NonEmptyStr] ],
237 default => sub { return [] },
238 );
239
240 The Tuple[PositiveInt, NonEmptyStr] type constraint checks that a value
241 is a two-element arrayref where the first element is a positive integer
242 and the second element is a non-empty string. For example:
243
244 my $br = Horse->new(
245 name => "Bold Ruler",
246 wins => [
247 [ 1956, "Futurity Stakes" ],
248 [ 1956, "Juvenile Stakes" ],
249 ],
250 );
251
252 As you can see, parameterized type constraints may be nested to
253 arbitrary depth, though of course the more detailed your checks become,
254 the slower they will perform.
255
256 It is possible to have tuples with variable length. For example, we may
257 wish to include the jockey name in our race wins when it is known.
258
259 use Types::Standard qw( ArrayRef Tuple Optional );
260 use Types::Common::Numeric qw( PositiveInt );
261 use Types::Common::String qw( NonEmptyStr );
262
263 has wins => (
264 is => 'ro',
265 isa => ArrayRef[
266 Tuple[ PositiveInt, NonEmptyStr, Optional[NonEmptyStr] ]
267 ],
268 default => sub { return [] },
269 );
270
271 The third element will be checked if it is present, but forgiven if it
272 is absent.
273
274 Or we could just allow tuples to contain an arbitrary list of strings
275 after the year and race name:
276
277 use Types::Standard qw( ArrayRef Tuple Str slurpy );
278 use Types::Common::Numeric qw( PositiveInt );
279 use Types::Common::String qw( NonEmptyStr );
280
281 has wins => (
282 is => 'ro',
283 isa => ArrayRef[
284 Tuple[ PositiveInt, NonEmptyStr, slurpy ArrayRef[Str] ]
285 ],
286 default => sub { return [] },
287 );
288
289 The "slurpy" indicator will "slurp" all the remaining items in the
290 tuple into an arrayref and check it against ArrayRef[Str].
291
292 It's even possible to do this:
293
294 use Types::Standard qw( ArrayRef Tuple Any slurpy );
295 use Types::Common::Numeric qw( PositiveInt );
296 use Types::Common::String qw( NonEmptyStr );
297
298 has wins => (
299 is => 'ro',
300 isa => ArrayRef[
301 Tuple[ PositiveInt, NonEmptyStr, slurpy Any ]
302 ],
303 default => sub { return [] },
304 );
305
306 With this type constraint, any elements after the first two will be
307 slurped into an arrayref and we don't check that arrayref at all. (In
308 fact, the implementation of the Tuple type is smart enough to not
309 bother creating the temporary arrayref to check.)
310
311 Dict is the equivalent of Tuple for checking values of hashrefs.
312
313 use Types::Standard qw( ArrayRef Dict Optional );
314 use Types::Common::Numeric qw( PositiveInt );
315 use Types::Common::String qw( NonEmptyStr );
316
317 has wins => (
318 is => 'ro',
319 isa => ArrayRef[
320 Dict[
321 year => PositiveInt,
322 race => NonEmptyStr,
323 jockey => Optional[NonEmptyStr],
324 ],
325 ],
326 default => sub { return [] },
327 );
328
329 An example of using it:
330
331 my $br = Horse->new(
332 name => "Bold Ruler",
333 wins => [
334 { year => 1956, race => "Futurity Stakes", jockey => "Eddie" },
335 { year => 1956, race => "Juvenile Stakes" },
336 ],
337 );
338
339 The slurpy indicator does work for Dict too:
340
341 Dict[
342 year => PositiveInt,
343 race => NonEmptyStr,
344 jockey => Optional[NonEmptyStr],
345 slurpy HashRef[Str], # other Str values allowed
346 ]
347
348 And "slurpy Any" means what you probably think it means:
349
350 Dict[
351 year => PositiveInt,
352 race => NonEmptyStr,
353 jockey => Optional[NonEmptyStr],
354 slurpy Any, # allow hashref to contain absolutely anything else
355 ]
356
357 Going back to our first example, there's an opportunity to refine our
358 ArrayRef constraint:
359
360 package Horse {
361 use Moo;
362 use Types::Standard qw( Str Num ArrayRef );
363 use namespace::autoclean;
364
365 has name => ( is => 'ro', isa => Str );
366 has gender => ( is => 'ro', isa => Str );
367 has age => ( is => 'rw', isa => Num );
368 has children => (
369 is => 'ro',
370 isa => ArrayRef[ InstanceOf["Horse"] ],
371 default => sub { return [] },
372 );
373 }
374
375 The InstanceOf["Horse"] type constraint checks that a value is a
376 blessed object in the Horse class. So the horse's children should be an
377 arrayref of other Horse objects.
378
379 Internally it just checks "$_->isa("Horse")" on each item in the
380 arrayref.
381
382 It is sometimes useful to instead check "$_->DOES($role)" or
383 "$_->can($method)" on an object. For example:
384
385 package MyAPI::Client {
386 use Moo;
387 use Types::Standard qw( HasMethods );
388
389 has ua => (is => 'ro', isa => HasMethods["get", "post"] );
390 }
391
392 The ConsumerOf and HasMethods parameterizable types allow you to easily
393 check roles and methods of objects.
394
395 The Enum parameterizable type allows you to accept a more limited set
396 of string values. For example:
397
398 use Types::Standard qw( Enum );
399 has gender => ( is => 'ro', isa => Enum["m","f"] );
400
401 Or if you want a little more flexibility, you can use StrMatch which
402 allows you to test strings against a regular expression:
403
404 use Types::Standard qw( StrMatch );
405 has gender => ( is => 'ro', isa => StrMatch[qr/^[MF]/i] );
406
407 Or StrLength to check the maximum and minimum length of a string:
408
409 use Types::Common::String qw( StrLength );
410 has name => ( is => 'ro', isa => StrLength[3, 100] );
411
412 The maximum can be omitted.
413
414 Similarly, the maximum and minimum values for a numeric type can be
415 expressed using IntRange and NumRange:
416
417 use Types::Common::Numeric qw( IntRange );
418 # values over 200 are probably an input error
419 has age => ( is => 'ro', isa => IntRange[0, 200] );
420
421 Parameterized type constraints are one of the most powerful features of
422 Type::Tiny, allowing a small set of constraints to be combined in
423 useful ways.
424
425 Type Coercions
426 It is often good practice to be liberal in what you accept.
427
428 package Horse {
429 use Moo;
430 use Types::Standard qw( Str Num ArrayRef Bool );
431 use namespace::autoclean;
432
433 ...; # name, gender, age, children, wins
434 has is_alive => ( is => 'rw', isa => Bool, coerce => 1 );
435 }
436
437 The "coerce" option indicates that if a value is given which does not
438 pass the Bool type constraint, then it should be coerced (converted)
439 into something that does.
440
441 The definition of Bool says that to convert a non-boolean to a bool,
442 you just do "!! $non_bool". So all of the following will be living
443 horses:
444
445 Horse->new(is_alive => 42)
446 Horse->new(is_alive => [])
447 Horse->new(is_alive => "false") # in Perl, string "false" is true!
448
449 Bool is the only type constraint in Types::Standard that has a coercion
450 defined for it. The NumericCode, UpperCaseStr, LowerCaseStr,
451 UpperCaseSimpleStr, and LowerCaseSimpleStr types from
452 Types::Common::String also have conversions defined.
453
454 The other built-in constraints do not define any coercions because it
455 would be hard to agree on what it means to coerce from, say, a HashRef
456 to an ArrayRef. Do we keep the keys? The values? Both?
457
458 But it is pretty simple to add your own coercions!
459
460 use Types::Standard qw( ArrayRef HashRef Str );
461 has things => (
462 is => 'rw',
463 isa => ArrayRef->plus_coercions(
464 HashRef, sub { [ values %$_ ] },
465 Str, sub { [ split /;/, $_ ] },
466 ),
467 coerce => 1,
468 );
469
470 (Don't ever forget the "coerce => 1"!)
471
472 If a hashref is provided, the values will be used, and if a string is
473 provided, it will be split on the semicolon. Of course, if an arrayref
474 if provided, it already passes the type constraint, so no conversion is
475 necessary.
476
477 The coercions should be pairs of "from types" and code to coerce the
478 value. The code can be a coderef (as above) or just string of Perl code
479 (as below). Strings of Perl code can usually be optimized better by
480 Type::Tiny's internals, so are generally preferred. Thanks to Perl's
481 "q{...}" operator, they can look just as clean and pretty as coderefs.
482
483 use Types::Standard qw( ArrayRef HashRef Str );
484 has things => (
485 is => 'rw',
486 isa => ArrayRef->plus_coercions(
487 HashRef, q{ values %$_ },
488 Str, q{ [ split /;/, $_ ] },
489 ),
490 coerce => 1,
491 );
492
493 Coercions are deeply applied automatically, so the following will do
494 what you expect.
495
496 has inputs => (
497 is => 'ro',
498 isa => ArrayRef->of(Bool),
499 coerce => 1
500 );
501
502 I am, of course, assuming you expect something like:
503
504 my $coerced = [ map { !!$_ } @$orig ];
505
506 If you were assuming that, congratulations! We are on the same
507 wavelength.
508
509 And of course you can still add more coercions to the inherited ones...
510
511 has inputs => (
512 is => 'ro',
513 isa => ArrayRef->of(Bool)->plus_coercions(Str, sub {...}),
514 coerce => 1
515 );
516
517 Method Parameters
518 So far we have just concentrated on the definition of object
519 attributes, but type constraints are also useful to validate method
520 parameters.
521
522 Let's remember our attribute for keeping track of a horse's race wins:
523
524 use Types::Standard qw( ArrayRef Tuple Optional );
525 use Types::Common::Numeric qw( PositiveInt );
526 use Types::Common::String qw( NonEmptyStr );
527
528 has wins => (
529 is => 'ro',
530 isa => ArrayRef[
531 Tuple[ PositiveInt, NonEmptyStr, Optional[NonEmptyStr] ]
532 ],
533 default => sub { return [] },
534 );
535
536 Because we don't trust outside code to push new entries onto this
537 array, let's define a method in our class to do it.
538
539 package Horse {
540 ...;
541
542 sub add_win {
543 my $self = shift;
544 my ($year, $race, $jockey) = @_;
545 my $win = [
546 $year,
547 $race,
548 $jockey ? $jockey : (),
549 ];
550 push @{ $self->wins }, $win;
551 return $self;
552 }
553 }
554
555 This works pretty well, but we're still not actually checking the
556 values of $year, $race, and $jockey. Let's use Type::Params for that:
557
558 package Horse {
559 use Types::Common::Numeric qw( PositiveInt );
560 use Types::Common::String qw( NonEmptyStr );
561 use Type::Params qw( compile );
562 ...;
563
564 sub add_win {
565 state $check = compile(
566 PositiveInt,
567 NonEmptyStr,
568 NonEmptyStr, { optional => 1 },
569 );
570
571 my $self = shift;
572 my ($year, $race, $jockey) = $check->(@_);
573 my $win = [
574 $year,
575 $race,
576 $jockey ? $jockey : (),
577 ];
578 push @{ $self->wins }, $win;
579 return $self;
580 }
581 }
582
583 The first time this method is called, it will compile a coderef called
584 $check. Then every time it is run, $check will be called to check the
585 method's parameters. It will throw an exception if they fail. $check
586 will also perform coercions if types have them (and you don't even need
587 to remember "coerce => 1"; it's always automatic) and can even add in
588 defaults:
589
590 state $check = compile(
591 PositiveInt,
592 NonEmptyStr,
593 NonEmptyStr, { default => sub { "Eddie" } },
594 );
595
596 On older versions of Perl (prior to 5.10), "state" variables are not
597 available. A workaround is to replace this:
598
599 sub foo {
600 state $x = bar();
601 ...;
602 }
603
604 With this:
605
606 { # outer braces prevent other subs seeing $x
607 my $x; # declare $x before sub foo()
608 sub foo {
609 $x = bar();
610 ...;
611 }
612 }
613
614 (While we're having a general Perl syntax lesson, I'll note that
615 &$check with an ampersand and no parentheses is a shortcut for
616 "$check->(@_)" and actually runs slightly faster because it reuses the
617 @_ array for the called coderef. A lot of people dislike calling subs
618 with an ampersand, so we will stick to the "$check->(@_)" syntax in
619 these examples. But do consider using the shortcut!)
620
621 The generalized syntax for "compile" is:
622
623 state $check = compile(
624 \%general_options,
625 TypeForFirstParam, \%options_for_first_param,
626 TypeForSecondParam, \%options_for_second_param,
627 ...,
628 );
629
630 As a shortcut for the "{ optional => 1 }}" option, you can just use
631 Optional like in Tuple.
632
633 state $check = compile(
634 PositiveInt,
635 NonEmptyStr,
636 Optional[NonEmptyStr],
637 );
638
639 You can also use 0 and 1 as shortcuts for Optional[Any] and Any. The
640 following checks that the first parameter is a positive integer, the
641 second parameter is required (but doesn't care what value it is) and
642 the third parameter is allowed but not required.
643
644 state $check = compile(PositiveInt, 1, 0);
645
646 It is possible to accept a variable number of values using "slurpy":
647
648 package Horse {
649 use Types::Common::Numeric qw( PositiveInt );
650 use Types::Common::String qw( NonEmptyStr );
651 use Types::Standard qw( ArrayRef slurpy );
652 use Type::Params qw( compile );
653 ...;
654
655 sub add_wins_for_year {
656 state $check = compile(
657 PositiveInt,
658 slurpy ArrayRef[NonEmptyStr],
659 );
660
661 my $self = shift;
662 my ($year, $races) = $check->(@_);
663 for my $race (@$races) {
664 push @{ $self->wins }, [$year, $win];
665 }
666 return $self;
667 }
668 }
669
670 It would be called like this:
671
672 $bold_ruler->add_wins_for_year(
673 1956,
674 "Futurity Stakes",
675 "Juvenile Stakes",
676 );
677
678 The additional parameters are slurped into an arrayref and checked
679 against ArrayRef[NonEmptyStr].
680
681 Optional parameters are only allowed after required parameters, and
682 slurpy parameters are only allowed at the end. (And there can only be a
683 at most one slurpy parameter!)
684
685 For methods that accept more than one or two parameters, it is often a
686 good idea to provide them as a hash. For example:
687
688 $horse->add_win(
689 year => 1956,
690 race => "Futurity Stakes",
691 jockey => "Eddie",
692 );
693
694 This can make your code more readable.
695
696 To accept named parameters, use "compile_named" instead of "compile".
697
698 package Horse {
699 use Types::Common::Numeric qw( PositiveInt );
700 use Types::Common::String qw( NonEmptyStr );
701 use Type::Params qw( compile_named );
702 ...;
703
704 sub add_win {
705 state $check = compile_named(
706 year => PositiveInt,
707 race => NonEmptyStr,
708 jockey => NonEmptyStr, { optional => 1 },
709 );
710
711 my $self = shift;
712 my $args = $check->(@_);
713 my $win = [
714 $args->{year},
715 $args->{race},
716 exists($args->{jockey}) ? $args->{jockey} : (),
717 ];
718 push @{ $self->wins }, $win;
719 return $self;
720 }
721 }
722
723 "compile" and "compile_named" work pretty much the same, except the
724 latter accepts named parameters instead of positional, and returns a
725 hashref.
726
727 It will automatically allow for a hashref to be provided instead of a
728 full hash. The following both work, but the $args variable will always
729 be given a hashref.
730
731 $horse->add_win({
732 year => 1956,
733 race => "Juvenile Stakes",
734 });
735 $horse->add_win(
736 year => 1956,
737 race => "Futurity Stakes",
738 jockey => "Eddie",
739 );
740
741 Well... I say "always" but you can tell "compile_named" to accept named
742 parameters but return a positional list of parameters:
743
744 package Horse {
745 use Types::Common::Numeric qw( PositiveInt );
746 use Types::Common::String qw( NonEmptyStr );
747 use Type::Params qw( compile_named );
748 ...;
749
750 sub add_win {
751 state $check = compile_named(
752 { named_to_list => 1 },
753 year => PositiveInt,
754 race => NonEmptyStr,
755 jockey => NonEmptyStr, { optional => 1 },
756 );
757
758 my $self = shift;
759 my ($year, $race, $jockey) = $check->(@_);
760 my $win = [
761 $year,
762 $race,
763 $jockey ? $jockey : (),
764 ];
765 push @{ $self->wins }, $win;
766 return $self;
767 }
768 }
769
770 Optional and slurpy named parameters are supported as you'd expect.
771
772 With named parameters, it can be easy to misspell keys in your method
773 definition. For example:
774
775 my $win = [
776 $args->{year},
777 $args->{race},
778 exists($args->{jockee}) ? $args->{jockey} : (),
779 ];
780
781 Note "jockee"! This can lead to hard-to-find bugs. There's a
782 "compile_named_oo" function which may help and can lead to cleaner
783 code.
784
785 package Horse {
786 use Types::Common::Numeric qw( PositiveInt );
787 use Types::Common::String qw( NonEmptyStr );
788 use Type::Params qw( compile_named_oo );
789 ...;
790
791 sub add_win {
792 state $check = compile_named_oo(
793 year => PositiveInt,
794 race => NonEmptyStr,
795 jockey => NonEmptyStr, { optional => 1 },
796 );
797
798 my $self = shift;
799 my $args = $check->(@_);
800 my $win = [
801 $args->year,
802 $args->race,
803 $args->has_jockey ? $args->jockey : (),
804 ];
805 push @{ $self->wins }, $win;
806 return $self;
807 }
808 }
809
810 Now $args is a blessed object that you can call methods on. There is of
811 course a performance penalty for this, but it's surprisingly small.
812
813 For more information on Type::Params, and third-party alternatives, see
814 Type::Tiny::Manual::Params.
815
817 Congratulations! I know this was probably a lot to take in, but you've
818 covered all of the essentials.
819
820 You can now set type constraints and coercions for attributes and
821 method parameters in Moo! You are familiar with a lot of the most
822 important and useful type constraints and understand parameterization
823 and how it can be used to build more specific type constraints.
824
825 (And I'll let you in on a secret. Using Type::Tiny with Moose or Mouse
826 instead of Moo is exactly the same. You can just replace "use Moo" with
827 "use Moose" in any of these examples and they should work fine!)
828
829 Here's your next step:
830
831 • Type::Tiny::Manual::UsingWithMoo2
832
833 Advanced use of Type::Tiny with Moo, including unions and
834 intersections, "stringifies_to", "numifies_to",
835 "with_attribute_values", and "where".
836
838 On very old versions of Moo "coerce => 1" is not supported. Instead you
839 will need to provide a coderef or object overloading "&{}" to coerce.
840 Type::Tiny can provide you with an overloaded object.
841
842 package Horse {
843 use Moo;
844 use Types::Standard qw( Str Num ArrayRef Bool );
845 use namespace::autoclean;
846
847 ...; # name, gender, age, children, wins
848 has is_alive => (
849 is => 'rw',
850 isa => Bool,
851 coerce => Bool->coercion, # overloaded object
852 );
853 }
854
855 If you have a very old version of Moo, please upgrade to at least Moo
856 1.006000 which was the version that added support for "coerce => 1".
857
859 Toby Inkster <tobyink@cpan.org>.
860
862 This software is copyright (c) 2013-2014, 2017-2021 by Toby Inkster.
863
864 This is free software; you can redistribute it and/or modify it under
865 the same terms as the Perl 5 programming language system itself.
866
868 THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
869 WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
870 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
871
872
873
874perl v5.32.1 2021-04-27Type::Tiny::Manual::UsingWithMoo(3)