Aion

 view release on metacpan or  search on metacpan

lib/Aion/Type.pm  view on Meta::CPAN

		name => "Range",
		args => [3, 5],
		init => [sub {
			@{$Aion::Type::SELF}{qw/min max/} = @{$Aion::Type::SELF->{args}};
		}],
		test => sub { $Aion::Type::SELF->{min} <= $_ && $_ <= $Aion::Type::SELF->{max} },
	);
	
	$Range->init;
	
	3 ~~ $Range  # -> 1
	4 ~~ $Range  # -> 1
	5 ~~ $Range  # -> 1
	
	2 ~~ $Range  # -> ""
	6 ~~ $Range  # -> ""

=head2 include ($element)

Checks whether the argument belongs to the class.

	my $PositiveInt = Aion::Type->new(
		name => "PositiveInt",
		test => sub { /^\d+$/ },
	);
	
	$PositiveInt->include(5) # -> 1
	$PositiveInt->include(-6) # -> ""

=head2 exclude ($element)

Checks that the argument does not belong to the class.

	my $PositiveInt = Aion::Type->new(
		name => "PositiveInt",
		test => sub { /^\d+$/ },
	);
	
	$PositiveInt->exclude(5)  # -> ""
	$PositiveInt->exclude(-6) # -> 1

=head2 coerce ($value)

Cast C<$value> to type if the cast from type and function is in C<< $self-E<gt>{coerce} >>.

Corresponds to the C<< E<gt>E<gt> >> operator.

	my $Int = Aion::Type->new(name => "Int", test => sub { /^-?\d+\z/ });
	my $Num = Aion::Type->new(name => "Num", test => sub { /^-?\d+(\.\d+)?\z/ });
	my $Bool = Aion::Type->new(name => "Bool", test => sub { /^(1|0|)\z/ });
	
	push @{$Int->{coerce}}, [$Bool, sub { 0+$_ }];
	push @{$Int->{coerce}}, [$Num, sub { int($_+.5) }];
	
	$Int->coerce(5.5)	 # => 6
	$Int->coerce(undef)  # => 0
	$Int->coerce("abc")  # => abc

=head2 detail ($element, $feature)

Generates an error message.

	my $Int = Aion::Type->new(name => "Int");
	
	$Int->detail(-5, "Feature car") # => Feature car must have the type Int. The it is -5!
	
	my $Num = Aion::Type->new(name => "Num", message => sub {
		"Error: $_ is'nt $Aion::Type::SELF->{property}!"
	});
	
	$Num->detail("x", "car") # => Error: x is'nt car!

=head2 validate ($element, $feature)

Checks C<$element> and throws a C<detail> message if the element does not belong to the class.

	my $PositiveInt = Aion::Type->new(
		name => "PositiveInt",
		test => sub { /^\d+$/ },
	);
	
	eval {
		$PositiveInt->validate(-1, "Neg")
	};
	$@ # ~> Neg must have the type PositiveInt. The it is -1

=head2 val_to_str ($val)

Converts C<$val> to a string.

	Aion::Type->new->val_to_str([1,2,{x=>6}]) # => [1, 2, {x => 6}]

=head2 instanceof ($type)

Determines that a type is a subtype of another C<$type> by type name.

Doesn't work in C<|> and C<~>. Doesn't check arguments.

	my $Int = Aion::Type->new(name => "Int");
	my $PositiveInt = Aion::Type->new(name => "PositiveInt", as => $Int);
	
	$PositiveInt->instanceof('Int');          # -> 1
	$PositiveInt->instanceof('PositiveInt');  # -> 1
	$Int->instanceof('PositiveInt');          # -> ""
	
	my $MyEnum = Aion::Type->new(name => "MyEnum", args => [3, 5, 'car']);
	($MyEnum & $PositiveInt)->instanceof('Int'); # -> 1

=head2 is_set_theoretic

Checks that the type is set-theoretic (ie - the C<|>, C<&> or C<~> operator).

=head2 simplify

If the expression has no values, it will return C<~Any>, otherwise it will return the expression.

Simplification of the expression in this function may appear in the future.

	package Aion::Types;
	
	my $type = (Enum[1,2] | Enum[2,3]) & Enum[2,3,4];

lib/Aion/Type.pm  view on Meta::CPAN

Reverse operation to C<identical>.

	my $Int = Aion::Type->new(name => "Int");
	my $PositiveInt = Aion::Type->new(name => "PositiveInt", as => $Int);
	
	$Int->distinct($PositiveInt) # -> 1
	$Int ne $PositiveInt         # -> 1

=head2 disjoint ($other)

A type does not overlap with another type.

=head2 subset ($type)

Specifies that it is a subset of the specified type.

=head2 superset ($type)

Specifies that it is a superset of the specified type.

=head2 subproper ($other)

A type is a strict subset of another.

=head2 superproper ($other)

A type is a strict superset of another.

=head2 equals ($other)

A type is equivalent to another type.

=head2 differs ($other)

A type is not equivalent to another type.

=head2 disjoint ($other)

A type has no overlap with another type.

=head2 intersects ($other)

A type has an intersection or intersections with another type.

=head2 make ($pkg)

Creates a subroutine with no arguments that returns a type.

	BEGIN {
		Aion::Type->new(name=>"Rim", test => sub { /^[IVXLCDM]+$/i })->make(__PACKAGE__);
	}
	
	"IX" ~~ Rim	 # => 1

If C<init> is specified, then each time the subroutine is used, a type will be created and initialized.

	eval { Aion::Type->new(name=>"Rim", init => sub {...})->make(__PACKAGE__) }; $@ # ~> init_where won't work in Rim

If the routine cannot be created, an exception is thrown.

	eval { Aion::Type->new(name=>"Rim")->make }; $@ # ~> syntax error

=head2 make_arg ($pkg)

Creates a subroutine with arguments that returns a type.

	BEGIN {
		Aion::Type->new(name=>"Len", test => sub {
			$Aion::Type::SELF->{args}[0] <= length($_) && length($_) <= $Aion::Type::SELF->{args}[1]
		})->make_arg(__PACKAGE__, 1);
	}
	
	"IX" ~~ Len[2,2] # => 1

If the routine cannot be created, an exception is thrown.

	eval { Aion::Type->new(name=>"Rim")->make_arg }; $@ # ~> syntax error

=head2 make_maybe_arg ($pkg)

Creates a subroutine with or without arguments.

	BEGIN {
		Aion::Type->new(
			name => "Enum123",
			test => sub { $_ ~~ [1,2,3] },
			a_test => sub { $_ ~~ $Aion::Type::SELF->{args} },
		)->make_maybe_arg(__PACKAGE__);
	}
	
	3 ~~ Enum123        # -> 1
	3 ~~ Enum123[4,5,6] # -> ""
	5 ~~ Enum123[4,5,6] # -> 1

If the routine cannot be created, an exception is thrown.

	eval { Aion::Type->new(name=>"Rim")->make_maybe_arg }; $@ # ~> syntax error

=head2 args ()

List of arguments.

=head2 name ()

Type name.

=head2 as ()

Parent type.

=head2 message (;&message)

Message accessor. Uses C<&message> to generate an error message.

=head2 title (;$title)

Header accessor (used to create the B<swagger> schema).

=head2 description (;$description)

Description accessor (used to create a B<swagger> schema).

=head2 example (;$example)

Example accessor (used to create the B<swagger> schema).

=head2 true ()

Always returns C<1>. Needed to specify a test for a type without C<where>.

=head2 clone ()

Clone type.

	my $type = Aion::Type->new(name => 'New');
	my $type10 = $type->clone(args => [10]);
	$type->stringify # => New
	$type10->stringify # => New[10]

=head2 is_primitive ()

This is a primitive type, that is, one in whose hierarchy there are no set-theoretic operators.

	Aion::Types::Int->is_primitive  # -> 1
	Aion::Types::Like->is_primitive # -> ""

=head2 is_union ()

This is a union of types.

	Aion::Types::Int->is_union # -> ""
	(Aion::Types::Int | Aion::Types::Int)->is_union  # -> 1

=head2 is_intersection ()

This is the intersection of types.

	Aion::Types::Int->is_intersection # -> ""
	(Aion::Types::Int & Aion::Types::Int)->is_intersection  # -> 1

=head2 is_exclude ()

This is a type exception.

	Aion::Types::Any->is_exclude # -> ""
	(~Aion::Types::Any)->is_exclude # -> 1
	Aion::Types::None->is_exclude # -> 1
	~Aion::Types::Any eq Aion::Types::None # -> 1

=head2 is_enum ()

This is an enumeration.



( run in 1.959 second using v1.01-cache-2.11-cpan-2e0ccfb7a10 )