Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
Specio::Declare(3)    User Contributed Perl Documentation   Specio::Declare(3)

NAME
       Specio::Declare - Specio	declaration subroutines

VERSION
       version 0.46

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 the caller.

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:

       o   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.

       o   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.

       o   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.

       o   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:

       o   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.

       o   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.

       o   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>.

       I am also usually active	on IRC as 'autarch' on "irc://irc.perl.org".

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 - 2020 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.32.1			  2020-03-14		    Specio::Declare(3)

NAME | VERSION | SYNOPSIS | DESCRIPTION | SUBROUTINES | DECLARATION HELPERS | PARAMETERIZED TYPES | SUPPORT | SOURCE | AUTHOR | COPYRIGHT AND LICENSE

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=Specio::Declare&sektion=3&manpath=FreeBSD+13.0-RELEASE+and+Ports>

home | help