Aion

 view release on metacpan or  search on metacpan

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

## N

Сокращение для `SELF->{N}`.

## message ($code)

Используется с `subtype` для вывода сообщения об ошибке, если значение исключает тип. Ð’ `$code` используется: `SELF` - текущий тип, `ARGS`, `A`, `B`, `C`, `D` - аÑ...

## coerce ($type, from => $from, via => $via)

Добавляет новое приведение (`$via`) к `$type` из `$from` типа.

```perl
BEGIN {
	subtype Four => where {4 eq $_};
}

"4a" ~~ Four # -> ""

Four->coerce("4a") # -> "4a"

coerce Four, from Str, via { 0+$_ };

Four->coerce("4a")	# -> 4

coerce Four, from ArrayRef, via { scalar @$_ };

Four->coerce([1,2,3])           # -> 3
Four->coerce([1,2,3]) ~~ Four   # -> ""
Four->coerce([1,2,3,4]) ~~ Four # -> 1
```

Может использовать параметры типа:

```perl
BEGIN {
	subtype 'Plus[acc]', as Num;
}
coerce &Plus, from Num, via { $_ + A };

Plus([5])->coerce(4) # -> 9
Plus([5]) >> 5 # -> 10
1 >> Plus[5] # -> 6
```

`coerce` выбрасывает исключения:

```perl
eval {coerce Int, via1 => 1}; $@  # ~> coerce Int unused keys left: via1
eval {coerce "x"}; $@  # ~> coerce x not Aion::Type!
eval {coerce Int}; $@  # ~> coerce Int: from is'nt Aion::Type!
eval {coerce Int, from "x"}; $@  # ~> coerce Int: from is'nt Aion::Type!
eval {coerce Int, from Num}; $@  # ~> coerce Int: via is not subroutine!
eval {coerce Int, (from=>Num, via=>"x")}; $@  # ~> coerce Int: via is not subroutine!
```

Стандартные приведения:

```perl
# Str from Undef — empty string
Str->coerce(undef) # -> ""

# Int from Num — rounded integer
Int->coerce(2.5)  # -> 3
Int->coerce(-2.5) # -> -3

# Bool from Any — 1 or ""
Bool->coerce([]) # -> 1
Bool->coerce(0)  # -> ""
```

## from ($type)

Синтаксический сахар для `coerce`.

## via ($code)

Синтаксический сахар для `coerce`.

# ATTRIBUTES

## :Isa (@signature)

Проверяет сигнатуру подпрограммы: аргументы и результаты.

```perl
sub minint($$) : Isa(Int => Int => Int) {
	my ($x, $y) = @_;
	$x < $y? $x : $y
}

minint 6, 5; # -> 5
eval {minint 5.5, 2}; $@ # ~> Arguments of method `minint` must have the type Tuple\[Int, Int\]\.

sub half($) : Isa(Int => Int) {
	my ($x) = @_;
	$x / 2
}

half 4; # -> 2
eval {half 5}; $@ # ~> Return of method `half` must have the type Int. The it is 2.5
```

# TYPES

## Any

Тип верхнего уровня в иерархии. Сопоставляет всё.

Нижний тип можно получить как `~Any`.

## Control

Тип верхнего уровня в конструкторах иерархии создает новые типы из любых типов.

## Union[A, B...]

Союз нескольких типов. Аналогичен оператору `$type1 | $type2`.

```perl
33  ~~ Union[Int, Ref] # -> 1

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

## Option[A]

Дополнительные ключи в `Dict`.

```perl
{a=>55} ~~ Dict[a=>Int, b => Option[Int]]          # -> 1
{a=>55, b=>31} ~~ Dict[a=>Int, b => Option[Int]]   # -> 1
{a=>55, b=>31.5} ~~ Dict[a=>Int, b => Option[Int]] # -> ""
```

## Wantarray[A, S]

Если подпрограмма возвращает разные значения в контексте массива и скаляра, то используется тип `Wantarray` с типом `A` для контекста массива Ð...

```perl
sub arr : Isa(PositiveInt => Wantarray[ArrayRef[PositiveInt], PositiveInt]) {
	my ($n) = @_;
	wantarray? 1 .. $n: $n
}

my @array = arr(3);
my $scalar = arr(3);

\@array # --> [1,2,3]
$scalar  # -> 3
```

## Item

Тип верхнего уровня в иерархии скалярных типов.

## External[type]

Правращает `type` в `Aion::Type`.

* Если `type` - `Aion::Type`, то возвращает его без изменений.
* Если `type` строка, то оборачивает его в `Object`.
* Если `type` можно вызвать, то оборачивает его в `Aion::Type->new(test => $type, ...)`. А если он имеет метод `coerce`, то будет его использовать для преобразован...

```perl
External['Aion'] # -> Object['Aion']
External[sub { /^x/ }] ~~ 'xyz' # -> 1

package MyInt {
	use overload "&{}" => sub {
		sub { /^[+-]?[0-9]+$/ }
	};
	
	sub coerce { /\./? int($_): $_ }
}

my $myint = bless {}, 'MyInt';

External([$myint]) ~~ '+123' # -> 1
External([$myint])->coerce(10.1) # => 10
External([$myint])->coerce('abc') # => abc
```

## Bool

`1` is true. `0`, `""` or `undef` is false.

```perl
1 ~~ Bool  # -> 1
0 ~~ Bool  # -> 1
undef ~~ Bool # -> 1
"" ~~ Bool # -> 1

2 ~~ Bool  # -> ""
[] ~~ Bool # -> ""
```

## Enum[A...]

Перечисление.

```perl
3 ~~ Enum[1,2,3];            # -> 1
"cat" ~~ Enum["cat", "dog"]; # -> 1
4 ~~ Enum[1,2,3];            # -> ""

Enum["cat"] <= Enum["cat", "dog"] # -> 1
Enum["cat", "dog"] <= Enum["cat", "dog"] # -> 1

Enum(["cat", "dog"])->disjoint(Enum[1]) # -> 1
Enum(["cat", "dog"])->disjoint(Enum["ret", "cat"]) # -> ""

Enum[1,2] <= Enum[1,2,3]          # -> 1
Enum[1,2] <= Enum[2,3]            # -> ""
Enum[1,2] == Enum[2,1]            # -> 1
Enum[1,2] < Enum[1,2,3]           # -> 1
Enum[1,2,3] > Enum[1,2]           # -> 1
Enum[1,2] == (Enum[1] | Enum[2])  # -> 1
```

## Maybe[A]

`undef` или тип в `[]`.

```perl
undef ~~ Maybe[Int] # -> 1
4 ~~ Maybe[Int]     # -> 1
"" ~~ Maybe[Int]    # -> ""
```

## Undef

Только `undef`.

```perl
undef ~~ Undef # -> 1
0 ~~ Undef     # -> ""
```

## Defined

Всё за исключением `undef`.

```perl
\0 ~~ Defined    # -> 1
undef ~~ Defined # -> ""
```

## Value

Определённые значения без ссылок.

```perl
3 ~~ Value  # -> 1
\3 ~~ Value    # -> ""
undef ~~ Value # -> ""
```

## Len[from?, to]

Определяет значение длины от `from` или 0 до `to`.

```perl
"1234" ~~ Len[3]   # -> ""
"123" ~~ Len[3]    # -> 1
"12" ~~ Len[3]     # -> 1
"" ~~ Len[1, 2]    # -> ""
"1" ~~ Len[1, 2]   # -> 1
"12" ~~ Len[1, 2]  # -> 1
"123" ~~ Len[1, 2] # -> ""

Len[3] <= Len[3] # -> 1
Len[3] <= Len[4] # -> 1
Len[3] <= Len[2] # -> ""
```

## Version

Perl версии.

```perl
1.1.0 ~~ Version   # -> 1
1.1.0.5 ~~ Version # -> 1
v1.1.0 ~~ Version  # -> 1
v1.1 ~~ Version    # -> 1
v1 ~~ Version      # -> 1
1.1 ~~ Version     # -> ""
"1.1.0" ~~ Version # -> ""
```

## Str

Строки, включая числа.

```perl
1.1 ~~ Str   # -> 1
"" ~~ Str    # -> 1
1.1.0 ~~ Str # -> ""
```

## Uni

Строки Unicode с флагом utf8 или если декодирование в utf8 происходит без ошибок.

```perl
"↭" ~~ Uni # -> 1
123 ~~ Uni # -> ""
do {no utf8; "↭" ~~ Uni} # -> 1
```

## Bin

Бинарные строки без флага utf8 и октетов с номерами меньше 128.

```perl
123 ~~ Bin # -> 1

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


```perl
\12   ~~ ScalarRef      # -> 1
\\12  ~~ ScalarRef      # -> ""
\-1.2 ~~ ScalarRef[Num] # -> 1
```

## RefRef`[A]

Ссылка на ссылку.

```perl
\12    ~~ RefRef                 # -> ""
\\12   ~~ RefRef                 # -> 1
\-1.2  ~~ RefRef[Num]            # -> ""
\\-1.2 ~~ RefRef[ScalarRef[Num]] # -> 1
```

## GlobRef

Ссылка на глоб.

```perl
\*A::a ~~ GlobRef # -> 1
*A::a ~~ GlobRef  # -> ""
```

## FileHandle

Файловый описатель.

```perl
\*A::a ~~ FileHandle         # -> ""
\*STDIN ~~ FileHandle        # -> 1

open my $fh, "<", "/dev/null";
$fh ~~ FileHandle	         # -> 1
close $fh;

opendir my $dh, ".";
$dh ~~ FileHandle	         # -> 1
closedir $dh;

use constant { PF_UNIX => 1, SOCK_STREAM => 1 };

socket my $sock, PF_UNIX, SOCK_STREAM, 0;
$sock ~~ FileHandle	         # -> 1
close $sock;
```

## ArrayRef`[A]

Ссылки на массивы.

```perl
[] ~~ ArrayRef	# -> 1
{} ~~ ArrayRef	# -> ""
[] ~~ ArrayRef[Num]	# -> 1
{} ~~ ArrayRef[Num]	# -> ''
[1, 1.1] ~~ ArrayRef[Num]	# -> 1
[1, undef] ~~ ArrayRef[Num]	# -> ""
```

## Lim[from?, to]

Ограничивает массивы от `from` или 0 до `to` элементов.

```perl
[] ~~ Lim[5]     # -> 1
[1..5] ~~ Lim[5] # -> 1
[1..6] ~~ Lim[5] # -> ""

[1..5] ~~ Lim[1,5] # -> 1
[1..6] ~~ Lim[1,5] # -> ""

[1] ~~ Lim[1,5] # -> 1
[] ~~ Lim[1,5]  # -> ""

Lim[0, 10] <= Lim[0, 20]        # -> 1
Lim[10, 'Inf'] <= Lim[0, 'Inf'] # -> 1

Lim[3] <= Lim[5]          # -> 1
Lim[3] <= Lim[2]          # -> ""
Lim[2,5] < Lim[1,6]       # -> 1
Lim[2,5] == Lim[2,5]      # -> 1
```

## HashRef`[H]

Ссылки на хеши.

```perl
{} ~~ HashRef # -> 1
\1 ~~ HashRef # -> ""

[]  ~~ HashRef[Int]           # -> ""
{x=>1, y=>2}  ~~ HashRef[Int] # -> 1
{x=>1, y=>""} ~~ HashRef[Int] # -> ""
```

## Object`[O]

Благословлённые ссылки.

```perl
bless(\(my $val=10), "A1") ~~ Object # -> 1
\(my $val=10) ~~ Object              # -> ""

bless(\(my $val=10), "A1") ~~ Object["A1"] # -> 1
bless(\(my $val=10), "A1") ~~ Object["B1"] # -> ""
```

## Me

Благословенные ссылки на объекты текущего пакета.

```perl
package A1 {
	use Aion;
	bless({}, __PACKAGE__) ~~ Me  # -> 1
	bless({}, "A2") ~~ Me         # -> ""

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

bless({}, "HasMethodsExample") ~~ HasMethods[qw/x1/]	# -> 1
"HasMethodsExample" ~~ HasMethods[qw/x3/]				# -> ""
"HasMethodsExample" ~~ HasMethods[qw/x1 x2 x3/]			# -> ""
"HasMethodsExample" ~~ HasMethods[qw/x1 x3/]			# -> ""
```

## Overload`[op...]

Объект или класс с перегруженными операторами.

```perl
package OverloadExample {
	use overload '""' => sub { "abc" };
}

"OverloadExample" ~~ Overload            # -> 1
bless({}, "OverloadExample") ~~ Overload # -> 1
"A" ~~ Overload                          # -> ""
bless({}, "A") ~~ Overload               # -> ""
```

И у него перегружены указанные операторы.

```perl
"OverloadExample" ~~ Overload['""'] # -> 1
"OverloadExample" ~~ Overload['|']  # -> ""
```

## InstanceOf[A...]

Класс или объект наследует классы из списка.

```perl
package Animal {}
package Cat { our @ISA = qw/Animal/ }
package Tiger { our @ISA = qw/Cat/ }


"Tiger" ~~ InstanceOf['Animal', 'Cat'] # -> 1
"Tiger" ~~ InstanceOf['Tiger']         # -> 1
"Tiger" ~~ InstanceOf['Cat', 'Dog']    # -> ""
```

## ConsumerOf[A...]

Класс или объект имеет указанные роли.

```perl
package NoneExample {}
package RoleExample { sub DOES { $_[1] ~~ [qw/Role1 Role2/] } }

'RoleExample' ~~ ConsumerOf[qw/Role1/] # -> 1
'RoleExample' ~~ ConsumerOf[qw/Role2 Role1/] # -> 1
bless({}, 'RoleExample') ~~ ConsumerOf[qw/Role3 Role2 Role1/] # -> ""

'NoneExample' ~~ ConsumerOf[qw/Role1/] # -> ""
```

## BoolLike

Проверяет 1, 0, "", undef или объект с перегруженным оператором `bool` или `0+` как `JSON::PP::Boolean`. Во втором случае вызывает оператор  `0+` и проверяет ре...

`BoolLike` вызывает оператор `0+` и проверяет результат.

```perl
package BoolLikeExample {
	use overload '0+' => sub { ${$_[0]} };
}

bless(\(my $x = 1 ), 'BoolLikeExample') ~~ BoolLike # -> 1
bless(\(my $x = 11), 'BoolLikeExample') ~~ BoolLike # -> ""

1 ~~ BoolLike     # -> 1
0 ~~ BoolLike     # -> 1
"" ~~ BoolLike    # -> 1
undef ~~ BoolLike # -> 1

package BoolLike2Example {
	use overload 'bool' => sub { ${$_[0]} };
}

bless(\(my $x = 1 ), 'BoolLike2Example') ~~ BoolLike # -> 1
bless(\(my $x = 11), 'BoolLike2Example') ~~ BoolLike # -> 1
```

## StrLike

Строка или объект с перегруженным оператором `""`.

```perl
"" ~~ StrLike # -> 1

package StrLikeExample {
	use overload '""' => sub { "abc" };
}

bless({}, "StrLikeExample") ~~ StrLike # -> 1

{} ~~ StrLike # -> ""
```

## RegexpLike

Регулярное выражение или объект с перегруженным оператором `qr`.

```perl
ref(qr//)  # => Regexp
Scalar::Util::reftype(qr//) # => REGEXP

my $regex = bless qr//, "A";
Scalar::Util::reftype($regex) # => REGEXP

$regex ~~ RegexpLike # -> 1
qr// ~~ RegexpLike   # -> 1
"" ~~ RegexpLike     # -> ""

package RegexpLikeExample {
 use overload 'qr' => sub { qr/abc/ };
}

"RegexpLikeExample" ~~ RegexpLike # -> ""
bless({}, "RegexpLikeExample") ~~ RegexpLike # -> 1
```

## CodeLike

Подпрограмма или объект с перегруженным оператором `&{}`.

```perl
sub {} ~~ CodeLike     # -> 1
\&CodeLike ~~ CodeLike # -> 1
{} ~~ CodeLike         # -> ""
```

## ArrayLike`[A]

Массивы или объекты с перегруженным оператором или `@{}`.

```perl
{} ~~ ArrayLike      # -> ""
{} ~~ ArrayLike[Int] # -> ""

[] ~~ ArrayLike # -> 1

package ArrayLikeExample {
	use overload '@{}' => sub {
		shift->{array} //= []
	};
}

my $x = bless {}, 'ArrayLikeExample';
$x->[1] = 12;
$x->{array} # --> [undef, 12]

$x ~~ ArrayLike # -> 1

$x ~~ ArrayLike[Int] # -> ""

$x->[0] = 13;
$x ~~ ArrayLike[Int] # -> 1
```

## HashLike`[A]

Хэши или объекты с перегруженным оператором `%{}`.

```perl
{} ~~ HashLike  # -> 1
[] ~~ HashLike  # -> ""
[] ~~ HashLike[Int] # -> ""

package HashLikeExample {
	use overload '%{}' => sub {
		shift->[0] //= {}
	};
}

my $x = bless [], 'HashLikeExample';
$x->{key} = 12.3;
$x->[0]  # --> {key => 12.3}

$x ~~ HashLike      # -> 1
$x ~~ HashLike[Int] # -> ""
$x ~~ HashLike[Num] # -> 1
```

# Coerces

## Join\[R] as Str

Сктроковый тип с преобразованием массивов в строку через разделитель.

```perl
Join([' '])->coerce([qw/a b c/]) # => a b c

package JoinExample { use Aion;
	has s => (isa => Join[', '], coerce => 1);
}

JoinExample->new(s => [qw/a b c/])->s # => a, b, c

JoinExample->new(s => 'string')->s # => string
```

## Split\[S] as ArrayRef

```perl
Split([' '])->coerce('a b c') # --> [qw/a b c/]

package SplitExample { use Aion;
	has s => (isa => Split[qr/\s*,\s*/], coerce => 1);
}



( run in 1.779 second using v1.01-cache-2.11-cpan-d80b1682f3f )