Aion

 view release on metacpan or  search on metacpan

README.md  view on Meta::CPAN


```perl
package Externalis {
	use overload '&{}' => sub { sub { /^\d+$/ } };
	sub coerce { int $_ }
}

package ExIsa { use Aion;
	has x => (isa => Int);
	has y => (isa => sub { /^\d+$/ });
	has z => (isa => bless({}, 'Externalis'), coerce => 1);
}

ExIsa->new(x => 'str') # @-> Set feature x must have the type Int. The it is 'str'!
ExIsa->new->x # @-> Get feature x must have the type Int. The it is undef!
ExIsa->new(x => 10)->x			  # -> 10

ExIsa->new(y => 'abc') # @-> Set feature y must have the type External[CODE
ExIsa->new(z => ' 6 xyz')->z # -> 6
```

lib/Aion.md  view on Meta::CPAN


```perl
package Externalis {
	use overload '&{}' => sub { sub { /^\d+$/ } };
	sub coerce { int $_ }
}

package ExIsa { use Aion;
	has x => (isa => Int);
	has y => (isa => sub { /^\d+$/ });
	has z => (isa => bless({}, 'Externalis'), coerce => 1);
}

ExIsa->new(x => 'str') # @-> Set feature x must have the type Int. The it is 'str'!
ExIsa->new->x # @-> Get feature x must have the type Int. The it is undef!
ExIsa->new(x => 10)->x			  # -> 10

ExIsa->new(y => 'abc') # @-> Set feature y must have the type External[CODE
ExIsa->new(z => ' 6 xyz')->z # -> 6
```

lib/Aion.pm  view on Meta::CPAN

	%$REQUIRE = ();

	# TODO: очищать класс от вспомогательных функций
	#eval "package $cls; Aion->unimport; 1" or die;

	my $new = << 'END';
package %(cls)s {
	sub new {
		my ($cls, %value) = @_;
		$cls = ref $cls || $cls;
		my $self = bless {}, $cls;
		
%(initializers)s
		
		if(scalar keys %value) {
			my @fakekeys = sort keys %value;
			die "@fakekeys is'nt feature!" if @fakekeys == 1;
			local $" = ", ";
			die "@fakekeys is'nt features!"
		}

lib/Aion.pm  view on Meta::CPAN

=back

	package Externalis {
		use overload '&{}' => sub { sub { /^\d+$/ } };
		sub coerce { int $_ }
	}
	
	package ExIsa { use Aion;
		has x => (isa => Int);
		has y => (isa => sub { /^\d+$/ });
		has z => (isa => bless({}, 'Externalis'), coerce => 1);
	}
	
	ExIsa->new(x => 'str') # @-> Set feature x must have the type Int. The it is 'str'!
	ExIsa->new->x # @-> Get feature x must have the type Int. The it is undef!
	ExIsa->new(x => 10)->x			  # -> 10
	
	ExIsa->new(y => 'abc') # @-> Set feature y must have the type External[CODE
	ExIsa->new(z => ' 6 xyz')->z # -> 6

=head2 coerce => (1|0)

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

	lazy builder default trigger release cleaner
	make_reader make_writer make_predicate make_clearer
/);

#  Конструктор
sub new {
	my ($cls, $pkg, $name, @has) = @_;

	my $meta = $Aion::META{$pkg};

	bless {
		pkg => $pkg,
		name => $name,
		opt => {@has},
		has => \@has,
		construct => Aion::Meta::FeatureConstruct->new($pkg, $name),
		order => scalar keys %{$meta->{feature}},
		stash => {},
	}, ref $cls || $cls;
}

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

	set get has clear weaken
	accessor_name reader_name writer_name predicate_name clearer_name
	initer not_specified
	getter setter selfret
/);

#  Конструктор
sub new {
	my ($cls, $pkg, $name) = @_;

	bless {
		pkg => $pkg,
		name => $name,
		initializer => <<'END',
		if (exists $value{%(init_arg)s}) {
			%(initer)s
		}%(not_specified)s
END
		destroyer => <<'END',
		if (%(has)s) {
			eval {

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

package Aion::Meta::RequiresAnyFunction;

use common::sense;

use Aion::Meta::Util qw//;

Aion::Meta::Util::create_getters(qw/pkg name/);

sub new {
    my $cls = shift;
    bless {@_}, ref $cls || $cls;
}

sub compare {
    my ($self, $other) = @_;

   	die "Requires ${\ $self->stringify}" unless ref $other eq 'CODE';
}

sub stringify {
	my ($self) = @_;

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

package Aion::Meta::RequiresFeature;

use common::sense;

use Aion::Meta::Util qw//;
use List::Util qw/pairmap/;
use Scalar::Util qw/looks_like_number reftype blessed refaddr/;

Aion::Meta::Util::create_getters(qw/pkg name opt has/);

#  Конструктор
sub new {
	my ($cls, $pkg, $name, @has) = @_;
	bless {pkg => $pkg, name => $name, opt => {@has}, has => \@has}, ref $cls || $cls;
}

# Строковое представление фичи
sub stringify {
	my ($self) = @_;
	my $has = join ', ', pairmap { "$a => ${\
		Aion::Meta::Util::val_to_str($b)
	}" } @{$self->{has}};
	return "req $self->{name} => ($has) of $self->{pkg}";
}

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

			Aion::Meta::Util::val_to_str($feature_value)
		}) with ${\$self->stringify}"
			unless _deep_equal($value, $feature_value);
	}
}

# Сравнивает два значения
sub _deep_equal {
	my ($value, $other_value) = @_;

	if (blessed $value) {
		return "" unless blessed $other_value;

		if (overload::Method($value, '==')) {
			return "" unless $value == $other_value;
		}
		elsif (overload::Method($value, 'eq')) {
			return "" unless $value eq $other_value;
		}
		else {
			return "" unless refaddr $value == refaddr $other_value;
		}

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


use Aion::Meta::Util qw//;
use Aion::Types qw/Tuple/;
use Scalar::Util qw//;
use Sub::Util qw//;

Aion::Meta::Util::create_getters(qw/pkg subname signature referent wrapsub/);

sub new {
	my $cls = shift;
	bless {@_}, ref $cls || $cls;
}

sub wrap_sub {
	my ($self) = @_;

	my ($pkg, $subname, $signature, $referent) = @$self{qw/pkg subname signature referent/};

	my $args_of_meth = "Arguments of method `$subname`";
	my $returns_of_meth = "Returns of method `$subname`";
	my $return_of_meth = "Return of method `$subname`";

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

# SYNOPSIS

```perl
package My::Meta::Class {
	use Aion::Meta::Util;
	
	create_accessors qw/age/;
	create_getters qw/name/;
}

my $class = bless {name => 'car'}, 'My::Meta::Class';

$class->age(20);
$class->age  # => 20

$class->name  # => car
eval { $class->name('auto') }; $@ # ~> name is ro
```

# DESCRIPTION

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


=head1 SYNOPSIS

	package My::Meta::Class {
		use Aion::Meta::Util;
		
		create_accessors qw/age/;
		create_getters qw/name/;
	}
	
	my $class = bless {name => 'car'}, 'My::Meta::Class';
	
	$class->age(20);
	$class->age  # => 20
	
	$class->name  # => car
	eval { $class->name('auto') }; $@ # ~> name is ro

=head1 DESCRIPTION

Meta-classes that support the creation of features and function signatures (i.e., the internal kitchen of Aion) require their own small implementation, which this module provides.

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

# * test (CodeRef) — Чекер.
# * a_test (CodeRef) — Используется для проверки типа с аргументами, если аргументы не указаны, то используется test.
# * coerce (ArrayRef) — Массив преобразователей в этот тип: [Type => sub {}].
# * message (CodeRef) — Сообщение об ошибке.
# * title (Str) — Заголовок.
# * description (Str) — Описание.
# * example (Any) — Пример.
# * me (Str) — Только для типа Me: пакет в котором он был объявлен.
sub new {
	my $cls = shift;
	bless {@_}, $cls;
}

# Строковое представление
sub stringify {
	my ($self) = @_;

	my @args = map {
		UNIVERSAL::isa($_, __PACKAGE__)?
			$_->stringify:
			Aion::Meta::Util::val_to_str($_)

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

	}
	""
}

# Заголовок
sub title {
	my ($self, $title) = @_;
	if(@_ == 1) {
		$self->{title}
	} else {
		bless {%$self, title => $title}, ref $self
	}
}

# Описание
sub description {
	my ($self, $description) = @_;
	if(@_ == 1) {
		$self->{description}
	} else {
		bless {%$self, description => $description}, ref $self
	}
}

# Описание
sub example {
	my ($self, $description) = @_;
	if(@_ == 1) {
		$self->{example}
	} else {
		bless {%$self, example => $description}, ref $self
	}
}

# Создаёт функцию для типа
sub make {
	my ($self, $pkg) = @_;

	die "init_where won't work in $self" if $self->{init};

	my $var = "\$$self->{name}";

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

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.

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

\1 ~~ Ref # -> 1
[] ~~ Ref # -> 1
1 ~~ Ref  # -> ""
```

## Tied`[A]

Ссылка на связанную переменную.

```perl
package TiedHash { sub TIEHASH { bless {@_}, shift } }
package TiedArray { sub TIEARRAY { bless {@_}, shift } }
package TiedScalar { sub TIESCALAR { bless {@_}, shift } }

tie my %a, "TiedHash";
tie my @a, "TiedArray";
tie my $a, "TiedScalar";
my %b; my @b; my $b;

\%a ~~ Tied # -> 1
\@a ~~ Tied # -> 1
\$a ~~ Tied # -> 1

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

ref \abc()  # => SCALAR
\abc() ~~ LValueRef	# -> ""


package As {
	sub x : lvalue {
		shift->{x};
	}
}

my $x = bless {}, "As";
$x->x = 10;

$x->x # => 10
$x	# --> bless {x=>10}, "As"

ref \$x->x			 # => SCALAR
\$x->x ~~ LValueRef # -> ""
```

And on the end:

```perl
\1 ~~ LValueRef	# -> ""

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

[]  ~~ 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         # -> ""
}
```

## Map[K, V]

Как `HashRef`, но с типом для ключей.

```perl
{} ~~ Map[Int, Int]               # -> 1
{5 => 3} ~~ Map[Int, Int]         # -> 1

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


Хэш имеет перечисленные свойства. Кроме них он может иметь и другие.

```perl
[0, 1] ~~ HasProp[qw/0 1/] # -> ""

{a => 1, b => 2, c => 3} ~~ HasProp[qw/a b/] # -> 1
{a => 1, b => 2} ~~ HasProp[qw/a b/] # -> 1
{a => 1, c => 3} ~~ HasProp[qw/a b/] # -> ""

bless({a => 1, b => 3}, "A") ~~ HasProp[qw/a b/] # -> 1
```

## Like

Объект или строка.

```perl
"" ~~ Like # -> 1
1 ~~ Like  # -> 1
bless({}, "A") ~~ Like # -> 1
bless([], "A") ~~ Like # -> 1
bless(\(my $str = ""), "A") ~~ Like # -> 1
\1 ~~ Like  # -> ""
```

## HasMethods[m...]

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

```perl
package HasMethodsExample {
	sub x1 {}
	sub x2 {}
}

"HasMethodsExample" ~~ HasMethods[qw/x1 x2/]			# -> 1
bless({}, "HasMethodsExample") ~~ HasMethods[qw/x1 x2/] # -> 1
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...]

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

## 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         # -> ""

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

{} ~~ 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
```

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

{} ~~ 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

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

package Aion::Types;
# Типы-валидаторы для Aion

use common::sense;

use Aion::Meta::Util qw/subref_is_reachable/;
use Aion::Type;
use List::Util qw/all any first/;
use Exporter qw/import/;
require overload;
use Scalar::Util qw/looks_like_number reftype refaddr blessed/;
use Sub::Util qw//;

our @EXPORT = our @EXPORT_OK = grep {
	*{$Aion::Types::{$_}}{CODE}	&& !/^(_|(NaN|import|all|any|first|looks_like_number|reftype|refaddr|blessed|subref_is_reachable)\z)/n
} keys %Aion::Types::;

# Обрабатываем атрибут :Isa
sub MODIFY_CODE_ATTRIBUTES {
    my ($pkg, $referent, @attributes) = @_;

    grep { /^Isa\((.*)\)\z/s? do { _Isa($pkg, $referent, $1); 0 }: 1 } @attributes
}

sub _Isa {

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

				subtype "GlobRef", as &Ref, where { ref $_ eq "GLOB" };
					subtype "FileHandle", as &GlobRef,
						where { !!*$_{IO} };
				subtype "ArrayRef`[A]", as &Ref,
					where { ref $_ eq "ARRAY" }
					awhere { my $A = A; ref $_ eq "ARRAY" && all { $A->test } @$_ };
				subtype "HashRef`[A]", as &Ref,
					where { ref $_ eq "HASH" }
					awhere { my $A = A; ref $_ eq "HASH" && all { $A->test } values %$_ };
				subtype "Object`[class]", as &Ref,
					where { blessed($_) ne "" }
					awhere { blessed($_) && $_->isa(A) };
					subtype "Me", as &Object,
						init_where { SELF->{me} = caller(2) }
						where { UNIVERSAL::isa($_, SELF->{me}) };
				subtype "Map[K, V]", as &HashRef,
					where {
						my ($K, $V) = ARGS;
						while(my ($k, $v) = each %$_) {
							return "" unless $K->include($k) && $V->include($v);
						}
						return 1;

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

						where { SELF->{min} <= scalar keys %$_ && scalar keys %$_ <= SELF->{max} };
						
		subtype "Like", as (&Str | &Object);
			subtype "HasMethods[m...]", as &Like,
				where { my $x = $_; all { $x->can($_) } ARGS };
			subtype "Overload`[m...]", as &Like,
				where { !!overload::Overloaded($_) }
				awhere { my $x = $_; all { overload::Method($x, $_) } ARGS };
			subtype "InstanceOf[class...]", as &Like, where { my $x = $_; all { $x->isa($_) } ARGS };
			subtype "ConsumerOf[role...]", as &Like, where { my $x = $_; all { $x->DOES($_) } ARGS };
			subtype "StrLike", as &Like, where { !blessed($_) or !!overload::Method($_, '""') };
				subtype "Len[from, to?]", as &StrLike,
					init_where => $init_limit,
					where { SELF->{min} <= length($_) && length($_) <= SELF->{max} };

			subtype "NumLike", as &Like, where { looks_like_number($_) };
				subtype "Float", as &NumLike, where { -3.402823466E+38 <= $_ && $_ <= 3.402823466E+38 };

				my $_from; my $_to;
				subtype "Double", as &NumLike, where {
					$_from //= do { require Math::BigFloat; Math::BigFloat->new('-1.7976931348623157e+308') };

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

	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

=head2 Bool

C<1> is true. C<0>, C<""> or C<undef> is false.

	1 ~~ Bool  # -> 1

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

Link.

	\1 ~~ Ref # -> 1
	[] ~~ Ref # -> 1
	1 ~~ Ref  # -> ""

=head2 Tied`[A]

Link to the associated variable.

	package TiedHash { sub TIEHASH { bless {@_}, shift } }
	package TiedArray { sub TIEARRAY { bless {@_}, shift } }
	package TiedScalar { sub TIESCALAR { bless {@_}, shift } }
	
	tie my %a, "TiedHash";
	tie my @a, "TiedArray";
	tie my $a, "TiedScalar";
	my %b; my @b; my $b;
	
	\%a ~~ Tied # -> 1
	\@a ~~ Tied # -> 1
	\$a ~~ Tied # -> 1
	

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

	ref \abc()  # => SCALAR
	\abc() ~~ LValueRef	# -> ""
	
	
	package As {
		sub x : lvalue {
			shift->{x};
		}
	}
	
	my $x = bless {}, "As";
	$x->x = 10;
	
	$x->x # => 10
	$x	# --> bless {x=>10}, "As"
	
	ref \$x->x			 # => SCALAR
	\$x->x ~~ LValueRef # -> ""

And on the end:

	\1 ~~ LValueRef	# -> ""
	
	my $x = "abc";
	substr($x, 1, 1) = 10;

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

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

=head2 Object`[O]

Blessed links.

	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"] # -> ""

=head2 Me

Blessed references to objects of the current package.

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

=head2 Map[K, V]

Like C<HashRef>, but with a key type.

	{} ~~ Map[Int, Int]               # -> 1
	{5 => 3} ~~ Map[Int, Int]         # -> 1
	+{5.5 => 3} ~~ Map[Int, Int]      # -> ""
	{5 => 3.3} ~~ Map[Int, Int]       # -> ""

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

=head2 HasProp[p...]

A hash has the following properties. In addition to them, he may have others.

	[0, 1] ~~ HasProp[qw/0 1/] # -> ""
	
	{a => 1, b => 2, c => 3} ~~ HasProp[qw/a b/] # -> 1
	{a => 1, b => 2} ~~ HasProp[qw/a b/] # -> 1
	{a => 1, c => 3} ~~ HasProp[qw/a b/] # -> ""
	
	bless({a => 1, b => 3}, "A") ~~ HasProp[qw/a b/] # -> 1

=head2 Like

Object or string.

	"" ~~ Like # -> 1
	1 ~~ Like  # -> 1
	bless({}, "A") ~~ Like # -> 1
	bless([], "A") ~~ Like # -> 1
	bless(\(my $str = ""), "A") ~~ Like # -> 1
	\1 ~~ Like  # -> ""

=head2 HasMethods[m...]

An object or class has listed methods. In addition to them, there may be others.

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

=head2 Overload`[op...]

An object or class with overloaded operators.

	package OverloadExample {
		use overload '""' => sub { "abc" };
	}
	
	"OverloadExample" ~~ Overload            # -> 1
	bless({}, "OverloadExample") ~~ Overload # -> 1
	"A" ~~ Overload                          # -> ""
	bless({}, "A") ~~ Overload               # -> ""

And it has operators specified operators.

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

=head2 InstanceOf[A...]

A class or object inherits classes from a list.

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


=head2 ConsumerOf[A...]

A class or object has the specified roles.

	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/] # -> ""

=head2 BoolLike

Tests for 1, 0, "", undef, or an object with an overloaded C<bool> or C<0+> operator as C<JSON::PP::Boolean>. In the second case, it calls the C<0+> operator and checks the result as C<Bool>.

C<BoolLike> calls the C<0+> operator and checks the result.

	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

=head2 StrLike

A string or object overloaded with the C<""> operator.

	"" ~~ StrLike # -> 1
	
	package StrLikeExample {
		use overload '""' => sub { "abc" };
	}
	
	bless({}, "StrLikeExample") ~~ StrLike # -> 1
	
	{} ~~ StrLike # -> ""

=head2 RegexpLike

A regular expression or object with an overload of the C<qr> operator.

	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

=head2 CodeLike

A subroutine or object with an overload of the C<&{}> operator.

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

=head2 ArrayLike`[A]

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

	{} ~~ 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

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

	{} ~~ 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

=head1 Coerces

=head2 Join[R] as Str

t/aion.t  view on Meta::CPAN

# 
::done_testing; }; subtest 'isa => $type' => sub { 
package Externalis {
	use overload '&{}' => sub { sub { /^\d+$/ } };
	sub coerce { int $_ }
}

package ExIsa { use Aion;
	has x => (isa => Int);
	has y => (isa => sub { /^\d+$/ });
	has z => (isa => bless({}, 'Externalis'), coerce => 1);
}

eval {ExIsa->new(x => 'str')}; local ($::_g0 = $@, $::_e0 = 'Set feature x must have the type Int. The it is \'str\'!'); ok defined($::_g0) && $::_g0 =~ /^${\quotemeta $::_e0}/, 'ExIsa->new(x => \'str\') # @-> Set feature x must have the type Int. Th...
eval {ExIsa->new->x}; local ($::_g0 = $@, $::_e0 = 'Get feature x must have the type Int. The it is undef!'); ok defined($::_g0) && $::_g0 =~ /^${\quotemeta $::_e0}/, 'ExIsa->new->x # @-> Get feature x must have the type Int. The it is undef!' or ::d...
local ($::_g0 = do {ExIsa->new(x => 10)->x}, $::_e0 = do {10}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'ExIsa->new(x => 10)->x			  # -> 10' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

eval {ExIsa->new(y => 'abc')}; local ($::_g0 = $@, $::_e0 = 'Set feature y must have the type External[CODE'); ok defined($::_g0) && $::_g0 =~ /^${\quotemeta $::_e0}/, 'ExIsa->new(y => \'abc\') # @-> Set feature y must have the type External[CODE' or...
local ($::_g0 = do {ExIsa->new(z => ' 6 xyz')->z}, $::_e0 = do {6}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'ExIsa->new(z => \' 6 xyz\')->z # -> 6' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# 

t/aion/meta/requires-any-function.pm  view on Meta::CPAN

use common::sense; use open qw/:std :utf8/;  use Carp qw//; use File::Basename qw//; use File::Find qw//; use File::Slurper qw//; use File::Spec qw//; use File::Path qw//; use Scalar::Util qw//;  use Test::More 0.98;  BEGIN {     $SIG{__DIE__} = sub ...
# 
# use common::sense;
# 
# use Aion::Meta::Util qw//;
# 
# Aion::Meta::Util::create_getters(qw/pkg name/);
# 
# sub new {
#     my $cls = shift;
#     bless {@_}, ref $cls || $cls;
# }
# 
# sub compare {
#     my ($self, $other) = @_;
# 
#    	die "$self->{name} requires!" unless ref $other eq 'CODE';
# }
# 
# 1;
# 

t/aion/meta/requires-feature.pm  view on Meta::CPAN

use common::sense; use open qw/:std :utf8/;  use Carp qw//; use File::Basename qw//; use File::Find qw//; use File::Slurper qw//; use File::Spec qw//; use File::Path qw//; use Scalar::Util qw//;  use Test::More 0.98;  BEGIN {     $SIG{__DIE__} = sub ...
# 
# use common::sense;
# 
# use Aion::Meta::Util qw//;
# use List::Util qw/pairmap/;
# use Scalar::Util qw/looks_like_number reftype blessed refaddr/;
# 
# Aion::Meta::Util::create_getters(qw/pkg name opt has/);
# 
# #  Конструктор
# sub new {
# 	my ($cls, $pkg, $name, @has) = @_;
# 	bless {pkg => $pkg, name => $name, opt => {@has}, has => \@has}, ref $cls || $cls;
# }
# 
# # Строковое представление фичи
# sub stringify {
# 	my ($self) = @_;
# 	my $has = join ', ', pairmap { "$a => ${\
# 		Aion::Meta::Util::val_to_str($b)
# 	}" } @{$self->{has}};
# 	return "req $self->{name} => ($has) of $self->{pkg}";
# }

t/aion/meta/requires-feature.pm  view on Meta::CPAN

# 		$fail = 1, last unless _deep_equal($value, $other_value);
# 	}
# 
# 	die "Feature mismatch with ${\$self->stringify}" if $fail;
# }
# 
# # Сравнивает два значения
# sub _deep_equal {
# 	my ($value, $other_value) = @_;
# 
# 	if (blessed $value) {
# 		return "" unless blessed $other_value;
# 
# 		if (overload::Method($value, '==')) {
# 			return "" unless $value == $other_value;
# 		}
# 		elsif (overload::Method($value, 'eq')) {
# 			return "" unless $value eq $other_value;
# 		}
# 		else {
# 			return "" if refaddr $value != refaddr $other_value;
# 		}

t/aion/meta/util.t  view on Meta::CPAN

# # SYNOPSIS
# 
subtest 'SYNOPSIS' => sub { 
package My::Meta::Class {
	use Aion::Meta::Util;
	
	create_accessors qw/age/;
	create_getters qw/name/;
}

my $class = bless {name => 'car'}, 'My::Meta::Class';

$class->age(20);
local ($::_g0 = do {$class->age}, $::_e0 = "20"); ::ok $::_g0 eq $::_e0, '$class->age  # => 20' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

local ($::_g0 = do {$class->name}, $::_e0 = "car"); ::ok $::_g0 eq $::_e0, '$class->name  # => car' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
::like scalar do {eval { $class->name('auto') }; $@}, qr{name is ro}, 'eval { $class->name(\'auto\') }; $@ # ~> name is ro'; undef $::_g0; undef $::_e0;

# 
# # DESCRIPTION
# 

t/aion/types.t  view on Meta::CPAN

local ($::_g0 = do {External[sub { /^x/ }] ~~ 'xyz'}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'External[sub { /^x/ }] ~~ \'xyz\' # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

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

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

local ($::_g0 = do {External([$myint]) ~~ '+123'}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'External([$myint]) ~~ \'+123\' # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {External([$myint])->coerce(10.1)}, $::_e0 = "10"); ::ok $::_g0 eq $::_e0, 'External([$myint])->coerce(10.1) # => 10' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {External([$myint])->coerce('abc')}, $::_e0 = "abc"); ::ok $::_g0 eq $::_e0, 'External([$myint])->coerce(\'abc\') # => abc' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

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

t/aion/types.t  view on Meta::CPAN

local ($::_g0 = do {\1 ~~ Ref}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '\1 ~~ Ref # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {[] ~~ Ref}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '[] ~~ Ref # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {1 ~~ Ref}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '1 ~~ Ref  # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# 
# ## Tied`[A]
# 
# Ссылка на связанную переменную.
# 
::done_testing; }; subtest 'Tied`[A]' => sub { 
package TiedHash { sub TIEHASH { bless {@_}, shift } }
package TiedArray { sub TIEARRAY { bless {@_}, shift } }
package TiedScalar { sub TIESCALAR { bless {@_}, shift } }

tie my %a, "TiedHash";
tie my @a, "TiedArray";
tie my $a, "TiedScalar";
my %b; my @b; my $b;

local ($::_g0 = do {\%a ~~ Tied}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '\%a ~~ Tied # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {\@a ~~ Tied}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '\@a ~~ Tied # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {\$a ~~ Tied}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '\$a ~~ Tied # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

t/aion/types.t  view on Meta::CPAN

local ($::_g0 = do {ref \abc()}, $::_e0 = "SCALAR"); ::ok $::_g0 eq $::_e0, 'ref \abc()  # => SCALAR' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {\abc() ~~ LValueRef}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '\abc() ~~ LValueRef	# -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;


package As {
	sub x : lvalue {
		shift->{x};
	}
}

my $x = bless {}, "As";
$x->x = 10;

local ($::_g0 = do {$x->x}, $::_e0 = "10"); ::ok $::_g0 eq $::_e0, '$x->x # => 10' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {$x}, $::_e0 = do {bless {x=>10}, "As"}); ::is_deeply $::_g0, $::_e0, '$x	# --> bless {x=>10}, "As"' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

local ($::_g0 = do {ref \$x->x}, $::_e0 = "SCALAR"); ::ok $::_g0 eq $::_e0, 'ref \$x->x			 # => SCALAR' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {\$x->x ~~ LValueRef}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '\$x->x ~~ LValueRef # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# 
# And on the end:
# 

local ($::_g0 = do {\1 ~~ LValueRef}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '\1 ~~ LValueRef	# -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

t/aion/types.t  view on Meta::CPAN

local ($::_g0 = do {[]  ~~ HashRef[Int]}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '[]  ~~ HashRef[Int]           # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {{x=>1, y=>2}  ~~ HashRef[Int]}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '{x=>1, y=>2}  ~~ HashRef[Int] # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {{x=>1, y=>""} ~~ HashRef[Int]}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '{x=>1, y=>""} ~~ HashRef[Int] # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# 
# ## Object`[O]
# 
# Благословлённые ссылки.
# 
::done_testing; }; subtest 'Object`[O]' => sub { 
local ($::_g0 = do {bless(\(my $val=10), "A1") ~~ Object}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'bless(\(my $val=10), "A1") ~~ Object # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_...
local ($::_g0 = do {\(my $val=10) ~~ Object}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '\(my $val=10) ~~ Object              # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

local ($::_g0 = do {bless(\(my $val=10), "A1") ~~ Object["A1"]}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'bless(\(my $val=10), "A1") ~~ Object["A1"] # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0...
local ($::_g0 = do {bless(\(my $val=10), "A1") ~~ Object["B1"]}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'bless(\(my $val=10), "A1") ~~ Object["B1"] # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_...

# 
# ## Me
# 
# Благословенные ссылки на объекты текущего пакета.
# 
::done_testing; }; subtest 'Me' => sub { 
package A1 {
 use Aion;
local ($::_g0 = do {bless({}, __PACKAGE__) ~~ Me}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, ' bless({}, __PACKAGE__) ~~ Me  # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {bless({}, "A2") ~~ Me}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, ' bless({}, "A2") ~~ Me         # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
}

# 
# ## Map[K, V]
# 
# Как `HashRef`, но с типом для ключей.
# 
::done_testing; }; subtest 'Map[K, V]' => sub { 
local ($::_g0 = do {{} ~~ Map[Int, Int]}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '{} ~~ Map[Int, Int]               # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {{5 => 3} ~~ Map[Int, Int]}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '{5 => 3} ~~ Map[Int, Int]         # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

t/aion/types.t  view on Meta::CPAN

# 
# Хэш имеет перечисленные свойства. Кроме них он может иметь и другие.
# 
::done_testing; }; subtest 'HasProp[p...]' => sub { 
local ($::_g0 = do {[0, 1] ~~ HasProp[qw/0 1/]}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '[0, 1] ~~ HasProp[qw/0 1/] # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

local ($::_g0 = do {{a => 1, b => 2, c => 3} ~~ HasProp[qw/a b/]}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '{a => 1, b => 2, c => 3} ~~ HasProp[qw/a b/] # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $:...
local ($::_g0 = do {{a => 1, b => 2} ~~ HasProp[qw/a b/]}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '{a => 1, b => 2} ~~ HasProp[qw/a b/] # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_...
local ($::_g0 = do {{a => 1, c => 3} ~~ HasProp[qw/a b/]}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '{a => 1, c => 3} ~~ HasProp[qw/a b/] # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $:...

local ($::_g0 = do {bless({a => 1, b => 3}, "A") ~~ HasProp[qw/a b/]}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'bless({a => 1, b => 3}, "A") ~~ HasProp[qw/a b/] # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); ...

# 
# ## Like
# 
# Объект или строка.
# 
::done_testing; }; subtest 'Like' => sub { 
local ($::_g0 = do {"" ~~ Like}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '"" ~~ Like # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {1 ~~ Like}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '1 ~~ Like  # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {bless({}, "A") ~~ Like}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'bless({}, "A") ~~ Like # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {bless([], "A") ~~ Like}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'bless([], "A") ~~ Like # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {bless(\(my $str = ""), "A") ~~ Like}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'bless(\(my $str = ""), "A") ~~ Like # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0...
local ($::_g0 = do {\1 ~~ Like}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '\1 ~~ Like  # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# 
# ## HasMethods[m...]
# 
# Объект или класс имеет перечисленные методы. Кроме них может иметь и другие.
# 
::done_testing; }; subtest 'HasMethods[m...]' => sub { 
package HasMethodsExample {
	sub x1 {}
	sub x2 {}
}

local ($::_g0 = do {"HasMethodsExample" ~~ HasMethods[qw/x1 x2/]}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '"HasMethodsExample" ~~ HasMethods[qw/x1 x2/]			# -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef ...
local ($::_g0 = do {bless({}, "HasMethodsExample") ~~ HasMethods[qw/x1 x2/]}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'bless({}, "HasMethodsExample") ~~ HasMethods[qw/x1 x2/] # -> 1' or ::diag ::_struct_diff($::...
local ($::_g0 = do {bless({}, "HasMethodsExample") ~~ HasMethods[qw/x1/]}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'bless({}, "HasMethodsExample") ~~ HasMethods[qw/x1/]	# -> 1' or ::diag ::_struct_diff($::_g0, $...
local ($::_g0 = do {"HasMethodsExample" ~~ HasMethods[qw/x3/]}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '"HasMethodsExample" ~~ HasMethods[qw/x3/]				# -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::...
local ($::_g0 = do {"HasMethodsExample" ~~ HasMethods[qw/x1 x2 x3/]}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '"HasMethodsExample" ~~ HasMethods[qw/x1 x2 x3/]			# -> ""' or ::diag ::_struct_diff($::_g0, $::_e0)...
local ($::_g0 = do {"HasMethodsExample" ~~ HasMethods[qw/x1 x3/]}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '"HasMethodsExample" ~~ HasMethods[qw/x1 x3/]			# -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); unde...

# 
# ## Overload`[op...]
# 
# Объект или класс с перегруженными операторами.
# 
::done_testing; }; subtest 'Overload`[op...]' => sub { 
package OverloadExample {
	use overload '""' => sub { "abc" };
}

local ($::_g0 = do {"OverloadExample" ~~ Overload}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '"OverloadExample" ~~ Overload            # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {bless({}, "OverloadExample") ~~ Overload}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'bless({}, "OverloadExample") ~~ Overload # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; un...
local ($::_g0 = do {"A" ~~ Overload}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '"A" ~~ Overload                          # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {bless({}, "A") ~~ Overload}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'bless({}, "A") ~~ Overload               # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# 
# И у него есть операторы указанные операторы.
# 

local ($::_g0 = do {"OverloadExample" ~~ Overload['""']}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '"OverloadExample" ~~ Overload[\'""\'] # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_...
local ($::_g0 = do {"OverloadExample" ~~ Overload['|']}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '"OverloadExample" ~~ Overload[\'|\']  # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::...

# 
# ## InstanceOf[A...]

t/aion/types.t  view on Meta::CPAN

# ## ConsumerOf[A...]
# 
# Класс или объект имеет указанные роли.
# 
::done_testing; }; subtest 'ConsumerOf[A...]' => sub { 
package NoneExample {}
package RoleExample { sub DOES { $_[1] ~~ [qw/Role1 Role2/] } }

local ($::_g0 = do {'RoleExample' ~~ ConsumerOf[qw/Role1/]}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '\'RoleExample\' ~~ ConsumerOf[qw/Role1/] # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; unde...
local ($::_g0 = do {'RoleExample' ~~ ConsumerOf[qw/Role2 Role1/]}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '\'RoleExample\' ~~ ConsumerOf[qw/Role2 Role1/] # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef ...
local ($::_g0 = do {bless({}, 'RoleExample') ~~ ConsumerOf[qw/Role3 Role2 Role1/]}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'bless({}, \'RoleExample\') ~~ ConsumerOf[qw/Role3 Role2 Role1/] # -> ""' or ::diag ::...

local ($::_g0 = do {'NoneExample' ~~ ConsumerOf[qw/Role1/]}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '\'NoneExample\' ~~ ConsumerOf[qw/Role1/] # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; un...

# 
# ## BoolLike
# 
# Проверяет 1, 0, "", undef или объект с перегруженным оператором `bool` или `0+` как `JSON::PP::Boolean`. Во втором случае вызывает оператор  `0+` и проверяет р...
# 
# `BoolLike` вызывает оператор `0+` и проверяет результат.
# 
::done_testing; }; subtest 'BoolLike' => sub { 
package BoolLikeExample {
	use overload '0+' => sub { ${$_[0]} };
}

local ($::_g0 = do {bless(\(my $x = 1 ), 'BoolLikeExample') ~~ BoolLike}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'bless(\(my $x = 1 ), \'BoolLikeExample\') ~~ BoolLike # -> 1' or ::diag ::_struct_diff($::_g0, $...
local ($::_g0 = do {bless(\(my $x = 11), 'BoolLikeExample') ~~ BoolLike}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'bless(\(my $x = 11), \'BoolLikeExample\') ~~ BoolLike # -> ""' or ::diag ::_struct_diff($::_g0,...

local ($::_g0 = do {1 ~~ BoolLike}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '1 ~~ BoolLike     # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {0 ~~ BoolLike}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '0 ~~ BoolLike     # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {"" ~~ BoolLike}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '"" ~~ BoolLike    # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {undef ~~ BoolLike}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'undef ~~ BoolLike # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

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

local ($::_g0 = do {bless(\(my $x = 1 ), 'BoolLike2Example') ~~ BoolLike}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'bless(\(my $x = 1 ), \'BoolLike2Example\') ~~ BoolLike # -> 1' or ::diag ::_struct_diff($::_g0,...
local ($::_g0 = do {bless(\(my $x = 11), 'BoolLike2Example') ~~ BoolLike}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'bless(\(my $x = 11), \'BoolLike2Example\') ~~ BoolLike # -> 1' or ::diag ::_struct_diff($::_g0,...

# 
# ## StrLike
# 
# Строка или объект с перегруженным оператором `""`.
# 
::done_testing; }; subtest 'StrLike' => sub { 
local ($::_g0 = do {"" ~~ StrLike}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '"" ~~ StrLike # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

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

local ($::_g0 = do {bless({}, "StrLikeExample") ~~ StrLike}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'bless({}, "StrLikeExample") ~~ StrLike # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef ...

local ($::_g0 = do {{} ~~ StrLike}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '{} ~~ StrLike # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# 
# ## RegexpLike
# 
# Регулярное выражение или объект с перегруженным оператором `qr`.
# 
::done_testing; }; subtest 'RegexpLike' => sub { 
local ($::_g0 = do {ref(qr//)}, $::_e0 = "Regexp"); ::ok $::_g0 eq $::_e0, 'ref(qr//)  # => Regexp' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {Scalar::Util::reftype(qr//)}, $::_e0 = "REGEXP"); ::ok $::_g0 eq $::_e0, 'Scalar::Util::reftype(qr//) # => REGEXP' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

my $regex = bless qr//, "A";
local ($::_g0 = do {Scalar::Util::reftype($regex)}, $::_e0 = "REGEXP"); ::ok $::_g0 eq $::_e0, 'Scalar::Util::reftype($regex) # => REGEXP' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

local ($::_g0 = do {$regex ~~ RegexpLike}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$regex ~~ RegexpLike # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {qr// ~~ RegexpLike}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'qr// ~~ RegexpLike   # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {"" ~~ RegexpLike}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '"" ~~ RegexpLike     # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

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

local ($::_g0 = do {"RegexpLikeExample" ~~ RegexpLike}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '"RegexpLikeExample" ~~ RegexpLike # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {bless({}, "RegexpLikeExample") ~~ RegexpLike}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'bless({}, "RegexpLikeExample") ~~ RegexpLike # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $:...

# 
# ## CodeLike
# 
# Подпрограмма или объект с перегруженным оператором `&{}`.
# 
::done_testing; }; subtest 'CodeLike' => sub { 
local ($::_g0 = do {sub {} ~~ CodeLike}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'sub {} ~~ CodeLike     # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {\&CodeLike ~~ CodeLike}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '\&CodeLike ~~ CodeLike # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {{} ~~ CodeLike}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '{} ~~ CodeLike         # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

t/aion/types.t  view on Meta::CPAN

local ($::_g0 = do {{} ~~ ArrayLike[Int]}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '{} ~~ ArrayLike[Int] # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

local ($::_g0 = do {[] ~~ ArrayLike}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '[] ~~ ArrayLike # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

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

my $x = bless {}, 'ArrayLikeExample';
$x->[1] = 12;
local ($::_g0 = do {$x->{array}}, $::_e0 = do {[undef, 12]}); ::is_deeply $::_g0, $::_e0, '$x->{array} # --> [undef, 12]' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

local ($::_g0 = do {$x ~~ ArrayLike}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$x ~~ ArrayLike # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

local ($::_g0 = do {$x ~~ ArrayLike[Int]}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$x ~~ ArrayLike[Int] # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

$x->[0] = 13;
local ($::_g0 = do {$x ~~ ArrayLike[Int]}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$x ~~ ArrayLike[Int] # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

t/aion/types.t  view on Meta::CPAN

local ($::_g0 = do {{} ~~ HashLike}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '{} ~~ HashLike  # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {[] ~~ HashLike}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '[] ~~ HashLike  # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {[] ~~ HashLike[Int]}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '[] ~~ HashLike[Int] # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

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

my $x = bless [], 'HashLikeExample';
$x->{key} = 12.3;
local ($::_g0 = do {$x->[0]}, $::_e0 = do {{key => 12.3}}); ::is_deeply $::_g0, $::_e0, '$x->[0]  # --> {key => 12.3}' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

local ($::_g0 = do {$x ~~ HashLike}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$x ~~ HashLike      # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {$x ~~ HashLike[Int]}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$x ~~ HashLike[Int] # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {$x ~~ HashLike[Num]}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$x ~~ HashLike[Num] # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;

# 
# # Coerces
# 



( run in 2.799 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )