Provided by: libspecio-perl_0.48-1_all bug

NAME

       Specio::Declare - Specio declaration subroutines

VERSION

       version 0.48

SYNOPSIS

           package MyApp::Type::Library;

           use parent 'Specio::Exporter';

           use Specio::Declare;
           use Specio::Library::Builtins;

           declare(
               'Foo',
               parent => t('Str'),
               where  => sub { $_[0] =~ /foo/i },
           );

           declare(
               'ArrayRefOfInt',
               parent => t( 'ArrayRef', of => t('Int') ),
           );

           my $even = anon(
               parent => t('Int'),
               inline => sub {
                   my $type      = shift;
                   my $value_var = shift;

                   return $value_var . ' % 2 == 0';
               },
           );

           coerce(
               t('ArrayRef'),
               from  => t('Foo'),
               using => sub { [ $_[0] ] },
           );

           coerce(
               $even,
               from  => t('Int'),
               using => sub { $_[0] % 2 ? $_[0] + 1 : $_[0] },
           );

           # Specio name is DateTime
           any_isa_type('DateTime');

           # Specio name is DateTimeObject
           object_isa_type( 'DateTimeObject', class => 'DateTime' );

           any_can_type(
               'Duck',
               methods => [ 'duck_walk', 'quack' ],
           );

           object_can_type(
               'DuckObject',
               methods => [ 'duck_walk', 'quack' ],
           );

           enum(
               'Colors',
               values => [qw( blue green red )],
           );

           intersection(
               'HashRefAndArrayRef',
               of => [ t('HashRef'), t('ArrayRef') ],
           );

           union(
               'IntOrArrayRef',
               of => [ t('Int'), t('ArrayRef') ],
           );

DESCRIPTION

       This package exports a set of type declaration helpers. Importing this package also causes it to create a
       "t" subroutine in the calling package.

SUBROUTINES

       This module exports the following subroutines.

   t('name')
       This subroutine lets you access any types you have declared so far, as well as any types you imported
       from another type library.

       If you pass an unknown name, it throws an exception.

   declare(...)
       This subroutine declares a named type. The first argument is the type name, followed by a set of
       key/value parameters:

       •   parent => $type

           The  parent  should  be  another  type  object.  Specifically,  it  can  be  anything  which does the
           Specio::Constraint::Role::Interface role. The parent can be a named or anonymous type.

       •   where => sub { ... }

           This is a subroutine which defines the type constraint. It will be  passed  a  single  argument,  the
           value  to check, and it should return true or false to indicate whether or not the value is valid for
           the type.

           This parameter is mutually exclusive with the "inline" parameter.

       •   inline => sub { ... }

           This is a subroutine that is called to generate inline code to validate the  type.  Inlining  can  be
           much  faster  than  simply  providing  a  subroutine  with  the  "where" parameter, but is often more
           complicated to get right.

           The inline generator is called as a method on the type with one argument. This argument is  a  string
           containing  the  variable name to use in the generated code. Typically this is something like '$_[0]'
           or '$value'.

           The inline generator subroutine should return a string of code representing a  single  term,  and  it
           should  not  be terminated with a semicolon. This allows the inlined code to be safely included in an
           "if" statement, for example. You can use "do { }" blocks and ternaries to  get  everything  into  one
           term.  Do  not  assign  to  the variable you are testing. This single term should evaluate to true or
           false.

           The inline generator is expected to include code to implement both  the  current  type  and  all  its
           parents. Typically, the easiest way to do this is to write a subroutine something like this:

             sub {
                 my $self = shift;
                 my $var  = shift;

                 return $self->parent->inline_check($var)
                     . ' and more checking code goes here';
             }

           Or, more concisely:

             sub { $_[0]->parent->inline_check( $_[1] ) . 'more code that checks $_[1]' }

           The "inline" parameter is mutually exclusive with the "where" parameter.

       •   message_generator => sub { ... }

           A  subroutine  to  generate  an  error  message  when  the type check fails. The default message says
           something like "Validation failed for type named Int declared  in  package  Specio::Library::Builtins
           (.../Specio/blib/lib/Specio/Library/Builtins.pm) at line 147 in sub named (eval) with value 1.1".

           You can override this to provide something more specific about the way the type failed.

           The  subroutine  you  provide will be called as a method on the type with two arguments. The first is
           the description of the type (the bit in the message above that starts with "type named Int  ..."  and
           ends  with  "...  in  sub  named  (eval)".  This  description says what the thing is and where it was
           defined.

           The second argument is the value that failed the type check, after any coercions that might have been
           applied.

   anon(...)
       This subroutine declares an anonymous type. It is identical to "declare" except that it expects a list of
       key/value parameters without a type name as the first parameter.

   coerce(...)
       This declares a coercion from one type to another. The first argument should be an object which does  the
       Specio::Constraint::Role::Interface  role. This can be either a named or anonymous type. This type is the
       type that the coercion is to.

       The remaining arguments are key/value parameters:

       •   from => $type

           This must be an object which does the Specio::Constraint::Role::Interface role. This is type that  we
           are coercing from. Again, this can be either a named or anonymous type.

       •   using => sub { ... }

           This  is a subroutine which defines the type coercion. It will be passed a single argument, the value
           to coerce. It should return a new value of the type this coercion is to.

           This parameter is mutually exclusive with the "inline" parameter.

       •   inline => sub { ... }

           This is a subroutine that is called to generate inline code to perform the coercion.

           The inline generator is called as a method on the type with one argument. This argument is  a  string
           containing  the  variable name to use in the generated code. Typically this is something like '$_[0]'
           or '$value'.

           The inline generator subroutine should return a string of code representing a  single  term,  and  it
           should  not  be terminated with a semicolon. This allows the inlined code to be safely included in an
           "if" statement, for example. You can use "do { }" blocks and ternaries to  get  everything  into  one
           term. This single term should evaluate to the new value.

DECLARATION HELPERS

       This module also exports some helper subs for declaring certain kinds of types:

   any_isa_type, object_isa_type
       The  "any_isa_type"  helper  creates  a type which accepts a class name or object of the given class. The
       "object_isa_type" helper creates a type which only accepts an object of the given class.

       These subroutines take a type name as the first argument. The remaining arguments  are  key/value  pairs.
       Currently  this  is  just  the "class" key, which should be a class name. This is the class that the type
       requires.

       The type name argument can be omitted to create an anonymous type.

       You can also pass just a single argument, in which case that will be used as both the type's name and the
       class for the constraint to check.

   any_does_type, object_does_type
       The "any_does_type" helper creates a type which accepts a class name or object which does the given role.
       The "object_does_type" helper creates a type which only accepts an object which does the given role.

       These subroutines take a type name as the first argument. The remaining arguments  are  key/value  pairs.
       Currently  this  is  just  the  "role"  key, which should be a role name. This is the class that the type
       requires.

       This should just work (I hope) with roles created by Moose, Mouse, and Moo (using Role::Tiny).

       The type name argument can be omitted to create an anonymous type.

       You can also pass just a single argument, in which case that will be used as both the type's name and the
       role for the constraint to check.

   any_can_type, object_can_type
       The "any_can_type" helper creates a type which accepts a class name or object with the given methods. The
       "object_can_type" helper creates a type which only accepts an object with the given methods.

       These subroutines take a type name as the first argument. The remaining arguments  are  key/value  pairs.
       Currently  this  is  just  the "methods" key, which can be either a string or array reference of strings.
       These strings are the required methods for the type.

       The type name argument can be omitted to create an anonymous type.

   enum
       This creates a type which accepts a string matching a given list of acceptable values.

       The first argument is the type name. The remaining arguments are key/value pairs. Currently this is  just
       the "values" key. This should an array reference of acceptable string values.

       The type name argument can be omitted to create an anonymous type.

   intersection
       This  creates  a  type  which is the intersection of two or more other types. A union only accepts values
       which match all of its underlying types.

       The first argument is the type name. The remaining arguments are key/value pairs. Currently this is  just
       the "of" key. This should an array reference of types.

       The type name argument can be omitted to create an anonymous type.

   union
       This  creates a type which is the union of two or more other types. A union accepts any of its underlying
       types.

       The first argument is the type name. The remaining arguments are key/value pairs. Currently this is  just
       the "of" key. This should an array reference of types.

       The type name argument can be omitted to create an anonymous type.

PARAMETERIZED TYPES

       You can create a parameterized type by calling "t" with additional parameters, like this:

         my $arrayref_of_int = t( 'ArrayRef', of => t('Int') );

         my $arrayref_of_hashref_of_int = t(
             'ArrayRef',
             of => t(
                 'HashRef',
                 of => t('Int'),
             ),
         );

       The  "t"  subroutine assumes that if it receives more than one argument, it should look up the named type
       and call "$type->parameterize(...)" with the additional arguments.

       If the named type cannot be parameterized, it throws an error.

       You can also call "$type->parameterize" directly if needed. See  Specio::Constraint::Parameterizable  for
       details.

SUPPORT

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

SOURCE

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

AUTHOR

       Dave Rolsky <autarch@urth.org>

COPYRIGHT AND LICENSE

       This software is Copyright (c) 2012 - 2022 by Dave Rolsky.

       This is free software, licensed under:

         The Artistic License 2.0 (GPL Compatible)

       The full text of the license can be found in the LICENSE file included with this distribution.

perl v5.34.0                                       2022-06-21                               Specio::Declare(3pm)