1Type::Tiny::Manual::UsiUnsgeWritChoOntthreirb(u3t)ed PerTlypDeo:c:uTmiennyt:a:tMiaonnual::UsingWithOther(3)
2
3
4

NAME

6       Type::Tiny::Manual::UsingWithOther - using Type::Tiny with
7       Class::InsideOut, Params::Check, and Object::Accessor.
8

MANUAL

10       The antlers crew aren't the only object-oriented programming toolkits
11       in Perl town. Although Type::Tiny might have been built with Moose,
12       Mouse, and Moo in mind, it can be used with other toolkits.
13
14       These toolkits are... well... hmm... okay... they exist.
15
16       If you are starting a new project, there's very little reason not to
17       use Class::Tiny, Moo, or Moose. So you're probably okay to skip this
18       part of the fine manual and go straight to
19       Type::Tiny::Manual::UsingWithTestMore.
20
21   Class::InsideOut
22       You want Class::InsideOut 1.13 or above, which has support for blessed
23       and overloaded objects (including Type::Tiny type constraints) for the
24       "get_hook" and "set_hook" options.
25
26         package Person {
27           use Class::InsideOut qw( public );
28           use Types::Standard qw( Str Int );
29           use Types::Common::Numeric qw( PositiveInt );
30           use Type::Params qw( compile );
31
32           # Type checks are really easy.
33           # Just supply the type as a set hook.
34           public name => my %_name, {
35             set_hook => Str,
36           };
37
38           # Define a type that silently coerces negative values
39           # to positive. It's silly, but it works as an example!
40           my $Years = PositiveInt->plus_coercions(Int, q{ abs($_) });
41
42           # Coercions are more annoying, but possible.
43           public age => my %_age, {
44             set_hook => sub { $_ = $Years->assert_coerce($_) },
45           };
46
47           # Parameter checking for methods is as expected.
48           sub get_older {
49             state $check = compile( $Years );
50             my $self = shift;
51             my ($years) = $check->(@_);
52             $self->_set_age($self->age + $years);
53           }
54         }
55
56   Params::Check and Object::Accessor
57       The Params::Check "allow()" function, the "allow" option for the
58       Params::Check "check()" function, and the input validation mechanism
59       for Object::Accessor all work in the same way, which is basically a
60       limited pure-Perl implementation of the smart match operator. While
61       this doesn't directly support Type::Tiny constraints, it does support
62       coderefs.  You can use Type::Tiny's "compiled_check" method to obtain a
63       suitable coderef.
64
65       Param::Check example:
66
67         my $tmpl = {
68           name => { allow => Str->compiled_check },
69           age  => { allow => Int->compiled_check },
70         };
71         check($tmpl, { name => "Bob", age => 32 })
72           or die Params::Check::last_error();
73
74       Object::Accessor example:
75
76         my $obj = Object::Accessor->new;
77         $obj->mk_accessors(
78           { name => Str->compiled_check },
79           { age  => Int->compiled_check },
80         );
81
82       Caveat: Object::Accessor doesn't die when a value fails to meet its
83       type constraint; instead it outputs a warning to STDERR. This behaviour
84       can be changed by setting "$Object::Accessor::FATAL = 1".
85
86   Class::Struct
87       This is proof-of-concept of how Type::Tiny can be used to constrain
88       attributes for Class::Struct. It's probably not a good idea to use this
89       in production as it slows down "UNIVERSAL::isa" globally.
90
91         use Types::Standard -types;
92         use Class::Struct;
93
94         {
95           my %MAP;
96           my $orig_isa = \&UNIVERSAL::isa;
97           *UNIVERSAL::isa = sub {
98             return $MAP{$1}->check($_[0])
99               if $_[1] =~ /^CLASSSTRUCT::TYPETINY::(.+)$/ && exists $MAP{$1};
100             goto $orig;
101           };
102           my $orig_dn = \&Type::Tiny::display_name;
103           *Type::Tiny::display_name = sub {
104             if (caller(1) eq 'Class::Struct') {
105               $MAP{$_[0]{uniq}} = $_[0];
106               return "CLASSSTRUCT::TYPETINY::".$_[0]{uniq};
107             }
108             goto $orig_dn;
109           };
110         }
111
112         struct Person => [ name => Str, age => Int ];
113
114         my $bob = Person->new(
115           name => "Bob",
116           age  => 21,
117         );
118
119         $bob->name("Robert");   # okay
120         $bob->name([]);         # dies
121

NEXT STEPS

123       Here's your next step:
124
125       •   Type::Tiny::Manual::UsingWithTestMore
126
127           Type::Tiny for test suites.
128

AUTHOR

130       Toby Inkster <tobyink@cpan.org>.
131
133       This software is copyright (c) 2013-2014, 2017-2021 by Toby Inkster.
134
135       This is free software; you can redistribute it and/or modify it under
136       the same terms as the Perl 5 programming language system itself.
137

DISCLAIMER OF WARRANTIES

139       THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
140       WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
141       MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
142
143
144
145perl v5.34.0                      2022-01-T2y1pe::Tiny::Manual::UsingWithOther(3)
Impressum