1Specio(3)             User Contributed Perl Documentation            Specio(3)
2
3
4

NAME

6       Specio - Type constraints and coercions for Perl
7

VERSION

9       version 0.48
10

SYNOPSIS

12           package MyApp::Type::Library;
13
14           use Specio::Declare;
15           use Specio::Library::Builtins;
16
17           declare(
18               'PositiveInt',
19               parent => t('Int'),
20               inline => sub {
21                   $_[0]->parent->inline_check( $_[1] )
22                       . ' && ( '
23                       . $_[1]
24                       . ' > 0 )';
25               },
26           );
27
28           # or ...
29
30           declare(
31               'PositiveInt',
32               parent => t('Int'),
33               where  => sub { $_[0] > 0 },
34           );
35
36           declare(
37               'ArrayRefOfPositiveInt',
38               parent => t(
39                   'ArrayRef',
40                   of => t('PositiveInt'),
41               ),
42           );
43
44           coerce(
45               'ArrayRefOfPositiveInt',
46               from  => t('PositiveInt'),
47               using => sub { [ $_[0] ] },
48           );
49
50           any_can_type(
51               'Duck',
52               methods => [ 'duck_walk', 'quack' ],
53           );
54
55           object_isa_type('MyApp::Person');
56

DESCRIPTION

58       The "Specio" distribution provides classes for representing type
59       constraints and coercion, along with syntax sugar for declaring them.
60
61       Note that this is not a proper type system for Perl. Nothing in this
62       distribution will magically make the Perl interpreter start checking a
63       value's type on assignment to a variable. In fact, there's no built-in
64       way to apply a type to a variable at all.
65
66       Instead, you can explicitly check a value against a type, and
67       optionally coerce values to that type.
68
69       My long-term goal is to replace Moose's built-in types and
70       MooseX::Types with this module.
71

WHAT IS A TYPE?

73       At it's core, a type is simply a constraint. A constraint is code that
74       checks a value and returns true or false. Most constraints are
75       represented by Specio::Constraint::Simple objects. However, there are
76       other type constraint classes for specialized kinds of constraints.
77
78       Types can be named or anonymous, and each type can have a parent type.
79       A type's constraint is optional because sometimes you may want to
80       create a named subtype of some existing type without adding additional
81       constraints.
82
83       Constraints can be expressed either in terms of a simple subroutine
84       reference or in terms of an inline generator subroutine reference. The
85       former is easier to write but the latter is preferred because it allow
86       for better optimization.
87
88       A type can also have an optional message generator subroutine
89       reference. You can use this to provide a more intelligent error message
90       when a value does not pass the constraint, though the default message
91       should suffice for most cases.
92
93       Finally, you can associate a set of coercions with a type. A coercion
94       is a subroutine reference (or inline generator, like constraints), that
95       takes a value of one type and turns it into a value that matches the
96       type the coercion belongs to.
97

BUILTIN TYPES

99       This distribution ships with a set of builtin types representing the
100       types provided by the Perl interpreter itself. They are arranged in a
101       hierarchy as follows:
102
103         Item
104             Bool
105             Maybe (of `a)
106             Undef
107             Defined
108                 Value
109                     Str
110                         Num
111                             Int
112                         ClassName
113                 Ref
114                     ScalarRef (of `a)
115                     ArrayRef (of `a)
116                     HashRef (of `a)
117                     CodeRef
118                     RegexpRef
119                     GlobRef
120                     FileHandle
121                     Object
122
123       The "Item" type accepts anything and everything.
124
125       The "Bool" type only accepts "undef", 0, or 1.
126
127       The "Undef" type only accepts "undef".
128
129       The "Defined" type accepts anything except "undef".
130
131       The "Num" and "Int" types are stricter about numbers than Perl is.
132       Specifically, they do not allow any sort of space in the number, nor do
133       they accept "Nan", "Inf", or "Infinity".
134
135       The "ClassName" type constraint checks that the name is valid and that
136       the class is loaded.
137
138       The "FileHandle" type accepts either a glob, a scalar filehandle, or
139       anything that isa IO::Handle.
140
141       All types accept overloaded objects that support the required
142       operation. See below for details.
143
144   Overloading
145       Perl's overloading is horribly broken and doesn't make much sense at
146       all.
147
148       However, unlike Moose, all type constraints allow overloaded objects
149       where they make sense.
150
151       For types where overloading makes sense, we explicitly check that the
152       object provides the type overloading we expect. We do not simply try to
153       use the object as the type in question and hope it works. This means
154       that these checks effectively ignore the "fallback" setting for the
155       overloaded object. In other words, an object that overloads
156       stringification will not pass the "Bool" type check unless it also
157       overloads boolification.
158
159       Most types do not check that the overloaded method actually returns
160       something that matches the constraint. This may change in the future.
161
162       The "Bool" type accepts an object that implements "bool" overloading.
163
164       The "Str" type accepts an object that implements string ("q{""}")
165       overloading.
166
167       The "Num" type accepts an object that implements numeric ("'0+'}")
168       overloading. The "Int" type does as well, but it will check that the
169       overloading returns an actual integer.
170
171       The "ClassName" type will accept an object with string overloading that
172       returns a class name.
173
174       To make this all more confusing, the "Value" type will never accept an
175       object, even though some of its subtypes will.
176
177       The various reference types all accept objects which provide the
178       appropriate overloading. The "FileHandle" type accepts an object which
179       overloads globification as long as the returned glob is an open
180       filehandle.
181

PARAMETERIZABLE TYPES

183       Any type followed by a type parameter "of `a" in the hierarchy above
184       can be parameterized. The parameter is itself a type, so you can say
185       you want an "ArrayRef of Int", or even an "ArrayRef of HashRef of
186       ScalarRef of ClassName".
187
188       When they are parameterized, the "ScalarRef" and "ArrayRef" types check
189       that the value(s) they refer to match the type parameter. For the
190       "HashRef" type, the parameter applies to the values (keys are never
191       checked).
192
193   Maybe
194       The "Maybe" type is a special parameterized type. It allows for either
195       "undef" or a value. All by itself, it is meaningless, since it is
196       equivalent to "Maybe of Item", which is equivalent to Item. When
197       parameterized, it accepts either an "undef" or the type of its
198       parameter.
199
200       This is useful for optional attributes or parameters. However, you're
201       probably better off making your code simply not pass the parameter at
202       all This usually makes for a simpler API.
203

REGISTRIES AND IMPORTING

205       Types are local to each package where they are used. When you "import"
206       types from some other library, you are actually making a copy of that
207       type.
208
209       This means that a type named "Foo" in one package may not be the same
210       as "Foo" in another package. This has potential for confusion, but it
211       also avoids the magic action at a distance pollution that comes with a
212       global type naming system.
213
214       The registry is managed internally by the Specio distribution's
215       modules, and is not exposed to your code. To access a type, you always
216       call "t('TypeName')".
217
218       This returns the named type or dies if no such type exists.
219
220       Because types are always copied on import, it's safe to create
221       coercions on any type. Your coercion from "Str" to "Int" will not be
222       seen by any other package, unless that package explicitly imports your
223       "Int" type.
224
225       When you import types, you import every type defined in the package you
226       import from. However, you can overwrite an imported type with your own
227       type definition. You cannot define the same type twice internally.
228

CREATING A TYPE LIBRARY

230       By default, all types created inside a package are invisible to other
231       packages.  If you want to create a type library, you need to inherit
232       from Specio::Exporter package:
233
234         package MyApp::Type::Library;
235
236         use parent 'Specio::Exporter';
237
238         use Specio::Declare;
239         use Specio::Library::Builtins;
240
241         declare(
242             'Foo',
243             parent => t('Str'),
244             where  => sub { $_[0] =~ /foo/i },
245         );
246
247       Now the MyApp::Type::Library package will export a single type named
248       "Foo". It does not re-export the types provided by
249       Specio::Library::Builtins.
250
251       If you want to make your library re-export some other libraries types,
252       you can ask for this explicitly:
253
254         package MyApp::Type::Library;
255
256         use parent 'Specio::Exporter';
257
258         use Specio::Declare;
259         use Specio::Library::Builtins -reexport;
260
261         declare( 'Foo, ... );
262
263       Now MyApp::Types::Library exports any types it defines, as well as all
264       the types defined in Specio::Library::Builtins.
265

DECLARING TYPES

267       Use the Specio::Declare module to declare types. It exports a set of
268       helpers for declaring types. See that module's documentation for more
269       details on these helpers.
270

USING SPECIO WITH Moose

272       This should just work. Use a Specio type anywhere you'd specify a type.
273

USING SPECIO WITH Moo

275       Using Specio with Moo is easy. You can pass Specio constraint objects
276       as "isa" parameters for attributes. For coercions, simply call
277       "$type->coercion_sub".
278
279           package Foo;
280
281           use Specio::Declare;
282           use Specio::Library::Builtins;
283           use Moo;
284
285           my $str_type = t('Str');
286           has string => (
287              is  => 'ro',
288              isa => $str_type,
289           );
290
291           my $ucstr = declare(
292               'UCStr',
293               parent => t('Str'),
294               where  => sub { $_[0] =~ /^[A-Z]+$/ },
295           );
296
297           coerce(
298               $ucstr,
299               from  => t('Str'),
300               using => sub { return uc $_[0] },
301           );
302
303           has ucstr => (
304               is     => 'ro',
305               isa    => $ucstr,
306               coerce => $ucstr->coercion_sub,
307           );
308
309       The subs returned by Specio use Sub::Quote internally and are suitable
310       for inlining.
311

USING SPECIO WITH OTHER THINGS

313       See Specio::Constraint::Simple for the API that all constraint objects
314       share.
315

Moose, MooseX::Types, and Specio

317       This module aims to supplant both Moose's built-in type system (see
318       Moose::Util::TypeConstraints aka MUTC) and MooseX::Types, which
319       attempts to patch some of the holes in the Moose built-in type design.
320
321       Here are some of the salient differences:
322
323       •   Types names are strings, but they're not global
324
325           Unlike Moose and MooseX::Types, type names are always local to the
326           current package. There is no possibility of name collision between
327           different modules, so you can safely use short type names.
328
329           Unlike MooseX::Types, types are strings, so there is no possibility
330           of colliding with existing class or subroutine names.
331
332       •   No type auto-creation
333
334           Types are always retrieved using the "t()" subroutine. If you pass
335           an unknown name to this subroutine it dies. This is different from
336           Moose and MooseX::Types, which assume that unknown names are class
337           names.
338
339       •   Anon types are explicit
340
341           With Moose and MooseX::Types, you use the same subroutine,
342           "subtype()", to declare both named and anonymous types. With
343           Specio, you use "declare()" for named types and "anon()" for
344           anonymous types.
345
346       •   Class and object types are separate
347
348           Moose and MooseX::Types have "class_type" and "duck_type". The
349           former type requires an object, while the latter accepts a class
350           name or object.
351
352           With Specio, the distinction between accepting an object versus
353           object or class is explicit. There are six declaration helpers,
354           "object_can_type", "object_does_type", "object_isa_type",
355           "any_can_type", "any_does_type", and "any_isa_type".
356
357       •   Overloading support is baked in
358
359           Perl's overloading is quite broken but ignoring it makes Moose's
360           type system frustrating to use in many cases.
361
362       •   Types can either have a constraint or inline generator, not both
363
364           Moose and MooseX::Types types can be defined with a subroutine
365           reference as the constraint, an inline generator subroutine, or
366           both. This is purely for backwards compatibility, and it makes the
367           internals more complicated than they need to be.
368
369           With Specio, a constraint can have either a subroutine reference or
370           an inline generator, not both.
371
372       •   Coercions can be inlined
373
374           I simply never got around to implementing this in Moose.
375
376       •   No crazy coercion features
377
378           Moose has some bizarre (and mostly) undocumented features relating
379           to coercions and parameterizable types. This is a misfeature.
380

OPTIONAL PREREQS

382       There are several optional prereqs that if installed will make this
383       distribution better in some way.
384
385       •   Ref::Util
386
387           Installing this will speed up a number of type checks for built-in
388           types.
389
390       •   XString
391
392           If this is installed it will be loaded instead of the B module if
393           you have Perl 5.10 or greater. This module is much more memory
394           efficient than loading all of B.
395
396       •   Sub::Util or Sub::Name
397
398           If one of these is installed then stack traces that end up in
399           Specio code will have much better subroutine names for any frames.
400

WHY THE NAME?

402       This distro was originally called "Type", but that's an awfully generic
403       top level namespace. Specio is Latin for for "look at" and "spec" is
404       the root for the word "species". It's short, relatively easy to type,
405       and not used by any other distro.
406

LONG-TERM PLANS

408       Eventually I'd like to see this distro replace Moose's internal type
409       system, which would also make MooseX::Types obsolete.
410

SUPPORT

412       Bugs may be submitted at
413       <https://github.com/houseabsolute/Specio/issues>.
414

SOURCE

416       The source code repository for Specio can be found at
417       <https://github.com/houseabsolute/Specio>.
418

DONATIONS

420       If you'd like to thank me for the work I've done on this module, please
421       consider making a "donation" to me via PayPal. I spend a lot of free
422       time creating free software, and would appreciate any support you'd
423       care to offer.
424
425       Please note that I am not suggesting that you must do this in order for
426       me to continue working on this particular software. I will continue to
427       do so, inasmuch as I have in the past, for as long as it interests me.
428
429       Similarly, a donation made in this way will probably not make me work
430       on this software much more, unless I get so many donations that I can
431       consider working on free software full time (let's all have a chuckle
432       at that together).
433
434       To donate, log into PayPal and send money to autarch@urth.org, or use
435       the button at <https://www.urth.org/fs-donation.html>.
436

AUTHOR

438       Dave Rolsky <autarch@urth.org>
439

CONTRIBUTORS

441       •   Chris White <chrisw@leehayes.com>
442
443       •   cpansprout <cpansprout@gmail.com>
444
445       •   Graham Knop <haarg@haarg.org>
446
447       •   Karen Etheridge <ether@cpan.org>
448
449       •   Vitaly Lipatov <lav@altlinux.ru>
450
452       This software is Copyright (c) 2012 - 2022 by Dave Rolsky.
453
454       This is free software, licensed under:
455
456         The Artistic License 2.0 (GPL Compatible)
457
458       The full text of the license can be found in the LICENSE file included
459       with this distribution.
460
461
462
463perl v5.36.0                      2022-07-22                         Specio(3)
Impressum