File Coverage

blib/lib/Type/Library.pm
Criterion Covered Total %
statement 220 220 100.0
branch 67 82 81.7
condition 45 59 76.2
subroutine 37 37 100.0
pod 11 11 100.0
total 380 409 92.9


line stmt bran cond sub pod time code
1             package Type::Library;
2              
3 287     287   423048 use 5.008001;
  287         1114  
4 287     287   1628 use strict;
  287         675  
  287         6637  
5 287     287   1560 use warnings;
  287         683  
  287         13601  
6              
7             BEGIN {
8 287     287   1113 $Type::Library::AUTHORITY = 'cpan:TOBYINK';
9 287         12869 $Type::Library::VERSION = '2.003_000';
10             }
11              
12             $Type::Library::VERSION =~ tr/_//d;
13              
14 287     287   112377 use Eval::TypeTiny qw< eval_closure set_subname type_to_coderef NICE_PROTOTYPES >;
  287         788  
  287         2016  
15 287     287   189832 use Scalar::Util qw< blessed refaddr >;
  287         719  
  287         15608  
16 287     287   73074 use Type::Tiny ();
  287         806  
  287         5565  
17 287     287   1690 use Types::TypeTiny ();
  287         607  
  287         264224  
18              
19             require Exporter::Tiny;
20             our @ISA = 'Exporter::Tiny';
21              
22 8     8   54 sub _croak ($;@) { require Error::TypeTiny; goto \&Error::TypeTiny::croak }
  8         55  
23              
24             ####
25             #### Hooks for Exporter::Tiny
26             ####
27              
28             # Handling for -base, -extends, and -utils tags.
29             #
30             sub _exporter_validate_opts {
31 1155     1155   1921161 my ( $class, $opts ) = ( shift, @_ );
32            
33 439         2180 $class->setup_type_library( @{$opts}{qw/ into utils extends /}, $opts )
34 1155 100 100     8738 if $_[0]{base} || $_[0]{extends};
35            
36 1155         6191 return $class->SUPER::_exporter_validate_opts( @_ );
37             }
38              
39             # In Exporter::Tiny, this method takes a sub name, a 'value' (i.e.
40             # potentially an options hashref for the export), and some global
41             # options, and returns a list of name+coderef pairs to actually
42             # export. We override it to provide some useful features.
43             #
44             sub _exporter_expand_sub {
45 20592     20592   880711 my ( $class, $name, $value, $globals ) = ( shift, @_ );
46            
47             # Handle exporting '+Type'.
48             #
49             # Note that this recurses, so if used in conjunction with the other
50             # special cases handled by this method, will still work.
51             #
52 20592 100 66     51618 if ( $name =~ /^\+(.+)/ and $class->has_type( "$1" ) ) {
53 13         125 my $type = $class->get_type( "$1" );
54 13         70 my $exported = $type->exportables;
55             return map $class->_exporter_expand_sub(
56             $_->{name},
57 13 50       57 +{ %{ $value || {} } },
  58         16965  
58             $globals,
59             ), @$exported;
60             }
61            
62             # Is the function being exported one which is associated with a
63             # type constraint? If so, which one. If not, then forget the rest
64             # and just use the superclass method.
65             #
66 20579 100 100     38594 if ( my $f = $class->meta->{'functions'}{$name}
67             and defined $class->meta->{'functions'}{$name}{'type'} ) {
68            
69 19587         32706 my $type = $f->{type};
70 19587         47472 my $tag = $f->{tags}[0];
71 19587         45953 my $typename = $type->name;
72            
73             # If $value has `of` or `where` options, then this is a
74             # custom type.
75             #
76 19587         29807 my $custom_type = 0;
77 19587         31176 for my $param ( qw/ of where / ) {
78 39174 100       73394 exists $value->{$param} or next;
79 3 50       6 defined $value->{-as} or _croak( "Parameter '-as' not supplied" );
80 3         13 $type = $type->$param( $value->{$param} );
81 3         6 $name = $value->{-as};
82 3         5 ++$custom_type;
83             }
84            
85             # If we're exporting a type itself, then export a custom
86             # function if they customized the type or want a Moose/Mouse
87             # type constraint.
88             #
89 19587 100       38501 if ( $tag eq 'types' ) {
90 9694         13781 my $post_method = q();
91 9694 50       19411 $post_method = '->mouse_type' if $globals->{mouse};
92 9694 50       16657 $post_method = '->moose_type' if $globals->{moose};
93 9694 100 66     29346 return ( $name => type_to_coderef( $type, post_method => $post_method ) )
94             if $post_method || $custom_type;
95             }
96            
97             # If they're exporting some other type of function, like
98             # 'to', 'is', or 'assert', then find the correct exportable
99             # by tag name, and return that.
100             #
101             # XXX: this will fail for tags like 'constants' where there
102             # will be multiple exportables which match!
103             #
104 19585 100 66     42173 if ( $custom_type and $tag ne 'types' ) {
105 1         5 my $exportable = $type->exportables_by_tag( $tag, $typename );
106 1   33     8 return ( $value->{-as} || $exportable->{name}, $exportable->{code} );
107             }
108             }
109            
110             # In all other cases, the superclass method will work.
111             #
112 20576         53865 return $class->SUPER::_exporter_expand_sub( @_ );
113             }
114              
115             # Mostly just rely on superclass to do the actual export, but add
116             # a couple of useful behaviours.
117             #
118             sub _exporter_install_sub {
119 20577     20577   770147 my ( $class, $name, $value, $globals, $sym ) = ( shift, @_ );
120            
121 20577         33925 my $into = $globals->{into};
122 20577         37319 my $type = $class->meta->{'functions'}{$name}{'type'};
123 20577         38250 my $tags = $class->meta->{'functions'}{$name}{'tags'};
124            
125             # Issue a warning if exporting a deprecated type constraint.
126             #
127             Exporter::Tiny::_carp(
128             "Exporting deprecated type %s to %s",
129             $type->qualified_name,
130             ref( $into ) ? "reference" : "package $into",
131 20577 50 100     63812 ) if ( defined $type and $type->deprecated and not $globals->{allow_deprecated} );
    100 100        
132            
133             # If exporting a type constraint into a real package, then
134             # add it to the package's type registry.
135             #
136 20577 100 66     125231 if ( !ref $into
      100        
      100        
137             and $into ne '-lexical'
138             and defined $type
139             and grep $_ eq 'types', @$tags ) {
140            
141             # If they're renaming it, figure out what name, and use that.
142             # XXX: `-as` can be a coderef, and can be in $globals in that case.
143 8978         26482 my ( $prefix ) = grep defined, $value->{-prefix}, $globals->{prefix}, q();
144 8978         19723 my ( $suffix ) = grep defined, $value->{-suffix}, $globals->{suffix}, q();
145 8978   66     31047 my $as = $prefix . ( $value->{-as} || $name ) . $suffix;
146            
147             $INC{'Type/Registry.pm'}
148             ? 'Type::Registry'->for_class( $into )->add_type( $type, $as )
149 8978 100       28555 : ( $Type::Registry::DELAYED{$into}{$as} = $type );
150             }
151            
152 20577         52582 $class->SUPER::_exporter_install_sub( @_ );
153             } #/ sub _exporter_install_sub
154              
155             sub _exporter_fail {
156 813     813   14190 my ( $class, $name, $value, $globals ) = ( shift, @_ );
157            
158             # Passing the `-declare` flag means that if a type isn't found, then
159             # we export a placeholder function instead of failing.
160 813 100       1807 if ( $globals->{declare} ) {
161             return (
162             $name,
163             type_to_coderef(
164             undef,
165             type_name => $name,
166 811   33     2585 type_library => $globals->{into} || _croak( "Parameter 'into' not supplied" ),
167             ),
168             );
169             } #/ if ( $globals->{declare...})
170            
171 2         7 return $class->SUPER::_exporter_fail( @_ );
172             } #/ sub _exporter_fail
173              
174             ####
175             #### Type library functionality
176             ####
177              
178             sub setup_type_library {
179 439     439 1 1288 my ( $class, $type_library, $install_utils, $extends, $opts ) = ( shift, @_ );
180            
181 439 50       1984 my @extends = ref( $extends ) ? @$extends : $extends ? $extends : ();
    100          
182 439 100       1536 unshift @extends, $class if $class ne __PACKAGE__;
183            
184 439 50       1228 if ( not ref $type_library ) {
185 287     287   2658 no strict "refs";
  287         766  
  287         62985  
186 439         726 push @{"$type_library\::ISA"}, $class;
  439         4873  
187 439         2272 ( my $file = $type_library ) =~ s{::}{/}g;
188 439   100     2257 $INC{"$file.pm"} ||= __FILE__;
189             }
190            
191 439 100       1250 if ( $install_utils ) {
192 4         1745 require Type::Utils;
193 4         56 'Type::Utils'->import(
194             { %$opts, into => $type_library },
195             '-default',
196             );
197             }
198            
199 439 100 66     9793 if ( @extends and not ref $type_library ) {
200 18         9430 require Type::Utils;
201 18         1255 my $wrapper = eval "sub { package $type_library; &Type::Utils::extends; }";
202 18         378 $wrapper->( @extends );
203             }
204             }
205              
206             sub meta {
207 287     287   2338 no strict "refs";
  287         748  
  287         10643  
208 287     287   1854 no warnings "once";
  287         779  
  287         93187  
209 131588 100   131588 1 347511 return $_[0] if blessed $_[0];
210 86255   100     102134 ${"$_[0]\::META"} ||= bless {}, $_[0];
  86255         348466  
211             }
212              
213             sub add_type {
214 13573     13573 1 40802 my $meta = shift->meta;
215 13573         33638 my $class = blessed( $meta ) ;
216            
217 13573 100       32196 _croak( 'Type library is immutable' ) if $meta->{immutable};
218            
219             my $type =
220             ref( $_[0] ) =~ /^Type::Tiny\b/ ? $_[0] :
221             blessed( $_[0] ) ? Types::TypeTiny::to_TypeTiny( $_[0] ) :
222 13569 100       60278 ref( $_[0] ) eq q(HASH) ? 'Type::Tiny'->new( library => $class, %{ $_[0] } ) :
  10435 50       61705  
    100          
223             "Type::Tiny"->new( library => $class, @_ );
224 13569         34788 my $name = $type->{name};
225            
226 13569 100       33519 if ( $meta->has_type( $name ) ) {
227 1         6 my $existing = $meta->get_type( $name );
228 1 50       8 return if $type->{uniq} == $existing->{uniq};
229 1         5 _croak( 'Type %s already exists in this library', $name );
230             }
231            
232 13568 50       31710 _croak( 'Type %s conflicts with coercion of same name', $name ) if $meta->has_coercion( $name );
233 13568 100       38558 _croak( 'Cannot add anonymous type to a library' ) if $type->is_anon;
234 13567   50     31748 $meta->{types} ||= {};
235 13567         33248 $meta->{types}{$name} = $type;
236            
237 287     287   2337 no strict "refs";
  287         812  
  287         11921  
238 287     287   2054 no warnings "redefine", "prototype";
  287         690  
  287         102371  
239            
240 13567         18099 for my $exportable ( @{ $type->exportables } ) {
  13567         32160  
241 54277         92045 my $name = $exportable->{name};
242 54277         69464 my $code = $exportable->{code};
243 54277         66626 my $tags = $exportable->{tags};
244             _croak( 'Function %s is provided by types %s and %s', $name, $meta->{'functions'}{$name}{'type'}->name, $type->name )
245 54277 100       111380 if $meta->{'functions'}{$name};
246 54276         141836 *{"$class\::$name"} = set_subname( "$class\::$name", $code );
  54276         242310  
247 54276         86246 push @{"$class\::EXPORT_OK"}, $name;
  54276         132055  
248 54276   100     93701 push @{ ${"$class\::EXPORT_TAGS"}{$_} ||= [] }, $name for @$tags;
  54276         62522  
  54276         203769  
249 54276         341129 $meta->{'functions'}{$name} = { type => $type, tags => $tags };
250             }
251            
252             $INC{'Type/Registry.pm'}
253             ? 'Type::Registry'->for_class( $class )->add_type( $type, $name )
254 13566 100       72158 : ( $Type::Registry::DELAYED{$class}{$name} = $type );
255            
256 13566         42501 return $type;
257             } #/ sub add_type
258              
259             # For Type::TinyX::Facets
260             # Only use this if you know what you're doing!
261             sub _remove_type {
262 1     1   16 my $meta = shift->meta;
263 1         10 my $type = $meta->get_type( $_[0] );
264 1         4 my $class = ref $meta;
265            
266 1 50       6 _croak( 'Type library is immutable' ) if $meta->{immutable};
267            
268 1         6 delete $meta->{types}{$type->name};
269            
270 287     287   2408 no strict "refs";
  287         793  
  287         11688  
271 287     287   1884 no warnings "redefine", "prototype";
  287         2146  
  287         159842  
272            
273 1         3 my @clean;
274             my $_scrub = sub {
275 8     8   17 my ( $arr, $name ) = @_;
276 8         206 @$arr = grep $_ ne $name, @$arr;
277 1         10 };
278 1         3 for my $exportable ( @{ $type->exportables } ) {
  1         4  
279 4         9 my $name = $exportable->{name};
280 4         7 push @clean, $name;
281 4         6 &$_scrub( \@{"$class\::EXPORT_OK"}, $name );
  4         21  
282 4         8 for my $t ( @{ $exportable->{tags} } ) {
  4         9  
283 4   50     6 &$_scrub( ${"$class\::EXPORT_TAGS"}{$t} ||= [], $name );
  4         17  
284             }
285 4         17 delete $meta->{'functions'}{$name};
286             }
287 1         16 eval {
288 1         7 require namespace::clean;
289 1         8 'namespace::clean'->clean_subroutines( $class, @clean );
290             };
291            
292             delete 'Type::Registry'->for_class( $class )->{$type->name}
293 1 50       236 if $INC{'Type/Registry.pm'};
294 1         5 delete $Type::Registry::DELAYED{$class}{$type->name};
295            
296 1         6 return $type;
297             } #/ sub _remove_type
298              
299             sub get_type {
300 4024     4024 1 41977 my $meta = shift->meta;
301 4024         19045 $meta->{types}{ $_[0] };
302             }
303              
304             sub has_type {
305 14826     14826 1 31295 my $meta = shift->meta;
306 14826         47758 exists $meta->{types}{ $_[0] };
307             }
308              
309             sub type_names {
310 96     96 1 449 my $meta = shift->meta;
311 96         207 keys %{ $meta->{types} };
  96         1686  
312             }
313              
314             sub add_coercion {
315 1013     1013 1 4030 my $meta = shift->meta;
316 1013         4941 my $class = blessed( $meta );
317            
318 1013 50       3536 _croak( 'Type library is immutable' ) if $meta->{immutable};
319            
320 1013         6361 require Type::Coercion;
321 1013 100       9452 my $c = blessed( $_[0] ) ? $_[0] : "Type::Coercion"->new( @_ );
322 1013         2893 my $name = $c->name;
323            
324 1013 50       2932 _croak( 'Coercion %s already exists in this library', $name ) if $meta->has_coercion( $name );
325 1013 100       3398 _croak( 'Coercion %s conflicts with type of same name', $name ) if $meta->has_type( $name );
326 1012 50       4442 _croak( 'Cannot add anonymous type to a library' ) if $c->is_anon;
327            
328 1012   50     3144 $meta->{coercions} ||= {};
329 1012         2904 $meta->{coercions}{$name} = $c;
330            
331 287     287   2530 no strict "refs";
  287         826  
  287         11905  
332 287     287   1843 no warnings "redefine", "prototype";
  287         728  
  287         74912  
333            
334 1012         3064 *{"$class\::$name"} = type_to_coderef( $c );
  1012         6994  
335 1012         2081 push @{"$class\::EXPORT_OK"}, $name;
  1012         4762  
336 1012   100     1738 push @{ ${"$class\::EXPORT_TAGS"}{'coercions'} ||= [] }, $name;
  1012         1734  
  1012         5688  
337 1012         11804 $meta->{'functions'}{$name} = { coercion => $c, tags => [ 'coercions' ] };
338              
339 1012         4240 return $c;
340             } #/ sub add_coercion
341              
342             sub get_coercion {
343 123     123 1 366 my $meta = shift->meta;
344 123         476 $meta->{coercions}{ $_[0] };
345             }
346              
347             sub has_coercion {
348 14581     14581 1 24919 my $meta = shift->meta;
349 14581         38583 exists $meta->{coercions}{ $_[0] };
350             }
351              
352             sub coercion_names {
353 96     96 1 319 my $meta = shift->meta;
354 96         199 keys %{ $meta->{coercions} };
  96         878  
355             }
356              
357             sub make_immutable {
358 368     368 1 1371 my $meta = shift->meta;
359 368         1279 my $class = ref( $meta );
360            
361 287     287   2338 no strict "refs";
  287         810  
  287         11461  
362 287     287   1874 no warnings "redefine", "prototype";
  287         835  
  287         52782  
363            
364 368         2955 for my $type ( values %{ $meta->{types} } ) {
  368         2801  
365 12271         33868 $type->coercion->freeze;
366 12271 100 66     27066 next unless $type->has_coercion && $type->coercion->frozen;
367 603         3774 for my $e ( $type->exportables_by_tag( 'to' ) ) {
368 603         2631 my $qualified_name = $class . '::' . $e->{name};
369 603         2107 *$qualified_name = set_subname( $qualified_name, $e->{code} );
370             }
371             }
372            
373 368         4758 $meta->{immutable} = 1;
374             }
375              
376             1;
377              
378             __END__
379              
380             =pod
381              
382             =encoding utf-8
383              
384             =for stopwords Moo(se)-compatible MooseX::Types-like
385              
386             =head1 NAME
387              
388             Type::Library - tiny, yet Moo(se)-compatible type libraries
389              
390             =head1 SYNOPSIS
391              
392             =for test_synopsis
393             BEGIN { die "SKIP: crams multiple modules into single example" };
394              
395             package Types::Mine {
396             use Scalar::Util qw(looks_like_number);
397             use Type::Library -base;
398             use Type::Tiny;
399            
400             my $NUM = "Type::Tiny"->new(
401             name => "Number",
402             constraint => sub { looks_like_number($_) },
403             message => sub { "$_ ain't a number" },
404             );
405            
406             __PACKAGE__->meta->add_type($NUM);
407            
408             __PACKAGE__->meta->make_immutable;
409             }
410            
411             package Ermintrude {
412             use Moo;
413             use Types::Mine qw(Number);
414             has favourite_number => (is => "ro", isa => Number);
415             }
416            
417             package Bullwinkle {
418             use Moose;
419             use Types::Mine qw(Number);
420             has favourite_number => (is => "ro", isa => Number);
421             }
422            
423             package Maisy {
424             use Mouse;
425             use Types::Mine qw(Number);
426             has favourite_number => (is => "ro", isa => Number);
427             }
428              
429             =head1 STATUS
430              
431             This module is covered by the
432             L<Type-Tiny stability policy|Type::Tiny::Manual::Policies/"STABILITY">.
433              
434             =head1 DESCRIPTION
435              
436             L<Type::Library> is a tiny class for creating MooseX::Types-like type
437             libraries which are compatible with Moo, Moose and Mouse.
438              
439             If you're reading this because you want to create a type library, then
440             you're probably better off reading L<Type::Tiny::Manual::Libraries>.
441              
442             =head2 Type library methods
443              
444             A type library is a singleton class. Use the C<meta> method to get a blessed
445             object which other methods can get called on. For example:
446              
447             Types::Mine->meta->add_type($foo);
448              
449             =begin trustme
450              
451             =item meta
452              
453             =end trustme
454              
455             =over
456              
457             =item C<< add_type($type) >> or C<< add_type(%opts) >>
458              
459             Add a type to the library. If C<< %opts >> is given, then this method calls
460             C<< Type::Tiny->new(%opts) >> first, and adds the resultant type.
461              
462             Adding a type named "Foo" to the library will automatically define four
463             functions in the library's namespace:
464              
465             =over
466              
467             =item C<< Foo >>
468              
469             Returns the Type::Tiny object.
470              
471             =item C<< is_Foo($value) >>
472              
473             Returns true iff $value passes the type constraint.
474              
475             =item C<< assert_Foo($value) >>
476              
477             Returns $value iff $value passes the type constraint. Dies otherwise.
478              
479             =item C<< to_Foo($value) >>
480              
481             Coerces the value to the type.
482              
483             =back
484              
485             =item C<< get_type($name) >>
486              
487             Gets the C<Type::Tiny> object corresponding to the name.
488              
489             =item C<< has_type($name) >>
490              
491             Boolean; returns true if the type exists in the library.
492              
493             =item C<< type_names >>
494              
495             List all types defined by the library.
496              
497             =item C<< add_coercion($c) >> or C<< add_coercion(%opts) >>
498              
499             Add a standalone coercion to the library. If C<< %opts >> is given, then
500             this method calls C<< Type::Coercion->new(%opts) >> first, and adds the
501             resultant coercion.
502              
503             Adding a coercion named "FooFromBar" to the library will automatically
504             define a function in the library's namespace:
505              
506             =over
507              
508             =item C<< FooFromBar >>
509              
510             Returns the Type::Coercion object.
511              
512             =back
513              
514             =item C<< get_coercion($name) >>
515              
516             Gets the C<Type::Coercion> object corresponding to the name.
517              
518             =item C<< has_coercion($name) >>
519              
520             Boolean; returns true if the coercion exists in the library.
521              
522             =item C<< coercion_names >>
523              
524             List all standalone coercions defined by the library.
525              
526             =item C<< import(@args) >>
527              
528             Type::Library-based libraries are exporters.
529              
530             =item C<< make_immutable >>
531              
532             Prevents new type constraints and coercions from being added to the
533             library, and also calls C<< $type->coercion->freeze >> on every
534             type constraint in the library.
535              
536             (Prior to Type::Library v2, C<make_immutable> would call
537             C<< $type->coercion->freeze >> on every constraint in the library,
538             but not prevent new type constraints and coercions from being added
539             to the library.)
540              
541             =back
542              
543             =head2 Type library exported functions
544              
545             Type libraries are exporters. For the purposes of the following examples,
546             assume that the C<Types::Mine> library defines types C<Number> and C<String>.
547              
548             # Exports nothing.
549             #
550             use Types::Mine;
551            
552             # Exports a function "String" which is a constant returning
553             # the String type constraint.
554             #
555             use Types::Mine qw( String );
556            
557             # Exports both String and Number as above.
558             #
559             use Types::Mine qw( String Number );
560            
561             # Same.
562             #
563             use Types::Mine qw( :types );
564            
565             # Exports "coerce_String" and "coerce_Number", as well as any other
566             # coercions
567             #
568             use Types::Mine qw( :coercions );
569            
570             # Exports a sub "is_String" so that "is_String($foo)" is equivalent
571             # to "String->check($foo)".
572             #
573             use Types::Mine qw( is_String );
574            
575             # Exports "is_String" and "is_Number".
576             #
577             use Types::Mine qw( :is );
578            
579             # Exports a sub "assert_String" so that "assert_String($foo)" is
580             # equivalent to "String->assert_return($foo)".
581             #
582             use Types::Mine qw( assert_String );
583            
584             # Exports "assert_String" and "assert_Number".
585             #
586             use Types::Mine qw( :assert );
587            
588             # Exports a sub "to_String" so that "to_String($foo)" is equivalent
589             # to "String->coerce($foo)".
590             #
591             use Types::Mine qw( to_String );
592            
593             # Exports "to_String" and "to_Number".
594             #
595             use Types::Mine qw( :to );
596            
597             # Exports "String", "is_String", "assert_String" and "coerce_String".
598             #
599             use Types::Mine qw( +String );
600            
601             # Exports everything.
602             #
603             use Types::Mine qw( :all );
604              
605             Type libraries automatically inherit from L<Exporter::Tiny>; see the
606             documentation of that module for tips and tricks importing from libraries.
607              
608             =head2 Type::Library's methods
609              
610             The above sections describe the characteristics of libraries built with
611             Type::Library. The following methods are available on Type::Library itself.
612              
613             =over
614              
615             =item C<< setup_type_library( $package, $utils, \@extends ) >>
616              
617             Sets up a package to be a type library. C<< $utils >> is a boolean
618             indicating whether to import L<Type::Utils> into the package.
619             C<< @extends >> is a list of existing type libraries the package
620             should extend.
621              
622             =back
623              
624             =head1 BUGS
625              
626             Please report any bugs to
627             L<https://github.com/tobyink/p5-type-tiny/issues>.
628              
629             =head1 SEE ALSO
630              
631             L<Type::Tiny::Manual>.
632              
633             L<Type::Tiny>, L<Type::Utils>, L<Types::Standard>, L<Type::Coercion>.
634              
635             L<Moose::Util::TypeConstraints>,
636             L<Mouse::Util::TypeConstraints>.
637              
638             =head1 AUTHOR
639              
640             Toby Inkster E<lt>tobyink@cpan.orgE<gt>.
641              
642             =head1 COPYRIGHT AND LICENCE
643              
644             This software is copyright (c) 2013-2014, 2017-2023 by Toby Inkster.
645              
646             This is free software; you can redistribute it and/or modify it under
647             the same terms as the Perl 5 programming language system itself.
648              
649             =head1 DISCLAIMER OF WARRANTIES
650              
651             THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
652             WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
653             MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.