Aion

 view release on metacpan or  search on metacpan

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

!ru:en
# NAME

Aion::Type - класс валидаторов

# SYNOPSIS

```perl
use Aion::Type;
use Aion::Types qw//;

my $Int = Aion::Type->new(name => "Int", test => sub { /^-?\d+$/ });
12   ~~ $Int # => 1
12.1 ~~ $Int # -> ""

my $Char = Aion::Type->new(name => "Char", test => sub { /^.\z/ });
$Char->include("a")	 # => 1
$Char->exclude("ab") # => 1

my $IntOrChar = $Int | $Char;
77   ~~ $IntOrChar # => 1
"a"  ~~ $IntOrChar # => 1
"ab" ~~ $IntOrChar # -> ""

my $Digit = $Int & $Char;
7  ~~ $Digit # => 1
77 ~~ $Digit # -> ""

"a" ~~ ~$Int; # => 1
5   ~~ ~$Int; # -> ""

eval { $Int->validate("a", "..Eval..") }; $@ # ~> ..Eval.. must have the type Int. The it is 'a'
```

# DESCRIPTION

Порождает валидаторы. Используется в `Aion::Types::subtype`.

# METHODS

## new (%ARGUMENTS)

Конструктор.

### ARGUMENTS

* name (Str) — Название типа.
* args (ArrayRef) — Список аргументов типа.
* init (CodeRef) — Инициализатор типа.
* test (CodeRef) — Чекер.
* a_test (CodeRef) — Чекер значений для типов с необязательными аргументами.
* coerce (ArrayRef[Tuple[Aion::Type, CodeRef]]) — Массив пар: тип и переход.

## stringify

Строковое преобразование объекта (имя с аргументами):

```perl
my $Char = Aion::Type->new(name => "Char");

$Char->stringify # => Char

my $Int = Aion::Type->new(
	name => "Int",
	args => [3, 5],
);

$Int->stringify  #=> Int[3, 5]
```

Операции так же преобразуются в строку:

```perl
($Int & $Char)->stringify   # => ( Int[3, 5] & Char )
($Int | $Char)->stringify   # => ( Int[3, 5] | Char )
(~$Int)->stringify		  # => ~Int[3, 5]
```

Операции — это объекты `Aion::Type` со специальными именами:

```perl
Aion::Type->new(name => "Exclude", args => [$Char])->stringify   # => ~Char
Aion::Type->new(name => "Union", args => [$Int, $Char])->stringify   # => ( Int[3, 5] | Char )
Aion::Type->new(name => "Intersection", args => [$Int, $Char])->stringify   # => ( Int[3, 5] & Char )
```

## test

Тестирует, что `$_` принадлежит классу.

```perl
my $PositiveInt = Aion::Type->new(

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


```perl
my $PositiveInt = Aion::Type->new(
	name => "PositiveInt",
	test => sub { /^\d+$/ },
);

$PositiveInt->include(5) # -> 1
$PositiveInt->include(-6) # -> ""
```

## exclude ($element)

Проверяет, что аргумент не принадлежит классу.

```perl
my $PositiveInt = Aion::Type->new(
	name => "PositiveInt",
	test => sub { /^\d+$/ },
);

$PositiveInt->exclude(5)  # -> ""
$PositiveInt->exclude(-6) # -> 1
```

## coerce ($value)

Привести `$value` к типу, если приведение из типа и функции находится в `$self->{coerce}`.

Соответствует оператору `>>`.

```perl
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
```

## detail ($element, $feature)

Формирует сообщение ошибки.

```perl
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!
```

## validate ($element, $feature)

Проверяет `$element` и выбрасывает сообщение `detail`, если элемент не принадлежит классу.

```perl
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
```

## val_to_str ($val)

Переводит `$val` в строку.

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

## instanceof ($type)

Определяет, что тип является подтипом другого `$type` по имени типа.

В `|` и `~` не заходит. Аргументы не проверяет.

```perl
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
```

## is_set_theoretic

Проверяет, что тип является множественно-теоритическим (т.е. – оператором `|`, `&` или `~`).

## simplify

Если выражение не имеет значений – вернёт `~Any`, иначе – выражение.

Упрощение выражения в этой функции возможно появится в будущем.

```perl
package Aion::Types;

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

$type->simplify->stringify # => ( ( Enum[1, 2] | Enum[2, 3] ) & Enum[2, 3, 4] )

my $range = Range[-10,0] & Range[4,8];
$range->simplify->stringify # => ~Any
```

## Any

Константа для типа включающего все значения.

```perl
package Aion::Type;

42 ~~ Any   # -> 1
42 ~~ None  # -> ""



( run in 0.570 second using v1.01-cache-2.11-cpan-d01c6094234 )