Aion

 view release on metacpan or  search on metacpan

lib/Aion.pm  view on Meta::CPAN

package Aion;
use 5.22.0;
no strict; no warnings; no diagnostics;
use common::sense;

our $VERSION = "0.4";

use Scalar::Util qw/blessed weaken/;
use Aion::Types qw//;

# Когда осуществлять проверки:
#   ro - только при выдаче
#   wo - только при установке
#   rw - при выдаче и уcтановке
#   no - никогда не проверять
use config ISA => 'rw';

sub export($@);

lib/Aion.pm  view on Meta::CPAN

		$feature->{clearer}->($self) if $feature and $feature->{clearer} and exists $self->{$name};
	}
    delete @$self{@_};
    $self
}

# Создаёт свойство
sub has(@) {
	my $property = shift;

    return exists $property->{$_[0]} if blessed $property;

	my $pkg = caller;
	is_aion $pkg;

    my %opt = @_;
	my $meta = $Aion::META{$pkg};

	# атрибуты
	for my $name (ref $property? @$property: $property) {

lib/Aion.pm  view on Meta::CPAN

	$self
}

# Устанавливает свойства и выдаёт объект и ошибки
sub create_from_params {
	my ($cls, %value) = @_;

	$cls = ref $cls || $cls;
	is_aion $cls;

	my $self = bless {}, $cls;

	my @init;
	my @required;
	my @errors;
    my $FEATURE = $Aion::META{$cls}{feature};

	while(my ($name, $feature) = each %$FEATURE) {

		if(exists $value{$name}) {
			my $val = delete $value{$name};

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


# конструктор
# * args (ArrayRef) — Список аргументов.
# * name (Str) — Имя метода.
# * init (CodeRef) — Инициализатор типа.
# * test (CodeRef) — Чекер.
# * a_test (CodeRef) — Используется в .
# * coerce (HashRef) — Массив преобразователей в этот тип: TypeName => sub {}.
sub new {
	my $cls = shift;
	bless {@_}, $cls;
}

# Символьное представление значения
sub val_to_str {
	my ($self, $v) = @_;
	!defined($v)			? "undef":
	looks_like_number($v)	? $v:
	ref($v)					? DDP::np($v, max_depth => 2, array_max => 13, hash_max => 13, string_max => 255):
	do {
		$v =~ s/[\\']/\\$&/g;

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

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

## Tied`[A]

The reference on the tied variable.

```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    # -> 1
\1 ~~ HashRef    # -> ""

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

## Object`[O]

The blessed values.

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

## Map[K, V]

As `HashRef`, but has type for keys also.

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

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


The hash has the properties.

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

The object or string.

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

## HasMethods[m...]

The object or the class has the methods.

```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...]

The object or the class is overloaded.

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

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

And it has the operators if arguments are specified.

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

## InstanceOf[A...]

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

The class or the object has the roles.

The presence of the role is checked by the `does` method.

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

## StrLike

String or object with overloaded operator `""`.

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

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

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

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

## RegexpLike

The regular expression or the object with overloaded operator `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

The subroutines.

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

# AUTHOR

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

# Типы-валидаторы для Aion

use 5.22.0;
no strict; no warnings; no diagnostics;
use common::sense;

use Aion::Type;
use Attribute::Handlers;
use List::Util qw/all any/;
use Exporter qw/import/;
use Scalar::Util qw/looks_like_number reftype blessed/;
use Sub::Util qw/prototype set_prototype subname set_subname/;

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

sub UNIVERSAL::Isa : ATTR(CODE) {
    my ($pkg, $symbol, $referent, $attr, $data, $phase, $file, $line) = @_;
    my $args_of_meth = "Arguments of method `" . *{$symbol}{NAME} . "`";
    my $returns_of_meth = "Returns of method `" . *{$symbol}{NAME} . "`";
    my $return_of_meth = "Return of method `" . *{$symbol}{NAME} . "`";

	my @signature = map { ref($_)? $_: $pkg->can($_)->() } @$data;

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

					awhere { ref $_ eq "REF" && A->include($$_) };
				subtype "GlobRef", as &Ref,
					where { ref $_ eq "GLOB" };
				subtype "ArrayRef`[A]", as &Ref,
					where { ref $_ eq "ARRAY" }
					awhere { my $A = A; ref $_ eq "ARRAY" && all { $A->test } @$_ };
				subtype "HashRef`[H]", as &Ref,
					where { ref $_ eq "HASH" }
					awhere { my $A = A; ref $_ eq "HASH" && all { $A->test } values %$_ };
				subtype "Object`[O]", as &Ref,
					where { blessed($_) ne "" }
					awhere { UNIVERSAL::isa($_, A) };
				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


The value is reference.

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

=head2 Tied`[A]

The reference on the tied 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


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

=head2 Object`[O]

The blessed values.

	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 Map[K, V]

As C<HashRef>, but has type for keys also.

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

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

=head2 HasProp[p...]

The hash has the properties.

	[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

The 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...]

The object or the class has the methods.

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

The object or the class is overloaded.

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

And it has the operators if arguments are specified.

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

=head2 InstanceOf[A...]

The class or the object inherits the list of classes.

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


The class or the object has the roles.

The presence of the role is checked by the C<does> method.

	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 StrLike

String or object with overloaded operator C<"">.

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

=head2 RegexpLike

The regular expression or the object with overloaded operator C<qr>.

	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

The subroutines.

	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 AUTHOR

Yaroslav O. Kosmina LL<mailto:dart@cpan.org>

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

done_testing; }; subtest 'Ref' => sub { 
::is scalar do {\1 ~~ Ref}, scalar do{1}, '\1 ~~ Ref    # -> 1';
::is scalar do {1 ~~ Ref}, scalar do{""}, '1 ~~ Ref     # -> ""';

# 
# ## Tied`[A]
# 
# The reference on the tied variable.
# 
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;

::is scalar do {\%a ~~ Tied}, scalar do{1}, '\%a ~~ Tied    # -> 1';
::is scalar do {\@a ~~ Tied}, scalar do{1}, '\@a ~~ Tied    # -> 1';
::is scalar do {\$a ~~ Tied}, scalar do{1}, '\$a ~~ Tied    # -> 1';

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

::is scalar do {ref \abc()}, "SCALAR", 'ref \abc()  # => SCALAR';
::is scalar do {\abc() ~~ LValueRef}, scalar do{""}, '\abc() ~~ LValueRef	# -> ""';


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

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

::is scalar do {$x->x}, "10", '$x->x # => 10';
::is_deeply scalar do {$x}, scalar do {bless {x=>10}, "As"}, '$x    # --> bless {x=>10}, "As"';

::is scalar do {ref \$x->x}, "SCALAR", 'ref \$x->x 			# => SCALAR';
::is scalar do {\$x->x ~~ LValueRef}, scalar do{""}, '\$x->x ~~ LValueRef # -> ""';

# 
# And on the end:
# 

::is scalar do {\1 ~~ LValueRef}, scalar do{""}, '\1 ~~ LValueRef	# -> ""';

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

::is scalar do {{} ~~ HashRef}, scalar do{1}, '{} ~~ HashRef    # -> 1';
::is scalar do {\1 ~~ HashRef}, scalar do{""}, '\1 ~~ HashRef    # -> ""';

::is scalar do {[]  ~~ HashRef[Int]}, scalar do{""}, '[]  ~~ HashRef[Int]    # -> ""';
::is scalar do {{x=>1, y=>2}  ~~ HashRef[Int]}, scalar do{1}, '{x=>1, y=>2}  ~~ HashRef[Int]    # -> 1';
::is scalar do {{x=>1, y=>""} ~~ HashRef[Int]}, scalar do{""}, '{x=>1, y=>""} ~~ HashRef[Int]    # -> ""';

# 
# ## Object`[O]
# 
# The blessed values.
# 
done_testing; }; subtest 'Object`[O]' => sub { 
::is scalar do {bless(\(my $val=10), "A1") ~~ Object}, scalar do{1}, 'bless(\(my $val=10), "A1") ~~ Object    # -> 1';
::is scalar do {\(my $val=10) ~~ Object}, scalar do{""}, '\(my $val=10) ~~ Object			    	# -> ""';

::is scalar do {bless(\(my $val=10), "A1") ~~ Object["A1"]}, scalar do{1}, 'bless(\(my $val=10), "A1") ~~ Object["A1"]   # -> 1';
::is scalar do {bless(\(my $val=10), "A1") ~~ Object["B1"]}, scalar do{""}, 'bless(\(my $val=10), "A1") ~~ Object["B1"]   # -> ""';

# 
# ## Map[K, V]
# 
# As `HashRef`, but has type for keys also.
# 
done_testing; }; subtest 'Map[K, V]' => sub { 
::is scalar do {{} ~~ Map[Int, Int]}, scalar do{1}, '{} ~~ Map[Int, Int]    		 # -> 1';
::is scalar do {{5 => 3} ~~ Map[Int, Int]}, scalar do{1}, '{5 => 3} ~~ Map[Int, Int]    # -> 1';
::is scalar do {+{5.5 => 3} ~~ Map[Int, Int]}, scalar do{""}, '+{5.5 => 3} ~~ Map[Int, Int] # -> ""';

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

# 
# The hash has the properties.
# 
done_testing; }; subtest 'HasProp[p...]' => sub { 
::is scalar do {[0, 1] ~~ HasProp[qw/0 1/]}, scalar do{""}, '[0, 1] ~~ HasProp[qw/0 1/]	# -> ""';

::is scalar do {{a => 1, b => 2, c => 3} ~~ HasProp[qw/a b/]}, scalar do{1}, '{a => 1, b => 2, c => 3} ~~ HasProp[qw/a b/]    # -> 1';
::is scalar do {{a => 1, b => 2} ~~ HasProp[qw/a b/]}, scalar do{1}, '{a => 1, b => 2} ~~ HasProp[qw/a b/]    # -> 1';
::is scalar do {{a => 1, c => 3} ~~ HasProp[qw/a b/]}, scalar do{""}, '{a => 1, c => 3} ~~ HasProp[qw/a b/]    # -> ""';

::is scalar do {bless({a => 1, b => 3}, "A") ~~ HasProp[qw/a b/]}, scalar do{1}, 'bless({a => 1, b => 3}, "A") ~~ HasProp[qw/a b/]    # -> 1';

# 
# ## Like
# 
# The object or string.
# 
done_testing; }; subtest 'Like' => sub { 
::is scalar do {"" ~~ Like}, scalar do{1}, '"" ~~ Like    	# -> 1';
::is scalar do {1 ~~ Like}, scalar do{1}, '1 ~~ Like    	# -> 1';
::is scalar do {bless({}, "A") ~~ Like}, scalar do{1}, 'bless({}, "A") ~~ Like    # -> 1';
::is scalar do {bless([], "A") ~~ Like}, scalar do{1}, 'bless([], "A") ~~ Like    # -> 1';
::is scalar do {bless(\(my $str = ""), "A") ~~ Like}, scalar do{1}, 'bless(\(my $str = ""), "A") ~~ Like    # -> 1';
::is scalar do {\1 ~~ Like}, scalar do{""}, '\1 ~~ Like    	# -> ""';

# 
# ## HasMethods[m...]
# 
# The object or the class has the methods.
# 
done_testing; }; subtest 'HasMethods[m...]' => sub { 
package HasMethodsExample {
	sub x1 {}
	sub x2 {}
}

::is scalar do {"HasMethodsExample" ~~ HasMethods[qw/x1 x2/]}, scalar do{1}, '"HasMethodsExample" ~~ HasMethods[qw/x1 x2/]    		# -> 1';
::is scalar do {bless({}, "HasMethodsExample") ~~ HasMethods[qw/x1 x2/]}, scalar do{1}, 'bless({}, "HasMethodsExample") ~~ HasMethods[qw/x1 x2/] # -> 1';
::is scalar do {bless({}, "HasMethodsExample") ~~ HasMethods[qw/x1/]}, scalar do{1}, 'bless({}, "HasMethodsExample") ~~ HasMethods[qw/x1/]    # -> 1';
::is scalar do {"HasMethodsExample" ~~ HasMethods[qw/x3/]}, scalar do{""}, '"HasMethodsExample" ~~ HasMethods[qw/x3/]    			# -> ""';
::is scalar do {"HasMethodsExample" ~~ HasMethods[qw/x1 x2 x3/]}, scalar do{""}, '"HasMethodsExample" ~~ HasMethods[qw/x1 x2 x3/]    		# -> ""';
::is scalar do {"HasMethodsExample" ~~ HasMethods[qw/x1 x3/]}, scalar do{""}, '"HasMethodsExample" ~~ HasMethods[qw/x1 x3/]    		# -> ""';

# 
# ## Overload`[op...]
# 
# The object or the class is overloaded.
# 
done_testing; }; subtest 'Overload`[op...]' => sub { 
package OverloadExample {
	use overload '""' => sub { "abc" };
}

::is scalar do {"OverloadExample" ~~ Overload}, scalar do{1}, '"OverloadExample" ~~ Overload    # -> 1';
::is scalar do {bless({}, "OverloadExample") ~~ Overload}, scalar do{1}, 'bless({}, "OverloadExample") ~~ Overload    # -> 1';
::is scalar do {"A" ~~ Overload}, scalar do{""}, '"A" ~~ Overload    				# -> ""';
::is scalar do {bless({}, "A") ~~ Overload}, scalar do{""}, 'bless({}, "A") ~~ Overload    	# -> ""';

# 
# And it has the operators if arguments are specified.
# 

::is scalar do {"OverloadExample" ~~ Overload['""']}, scalar do{1}, '"OverloadExample" ~~ Overload[\'""\']   # -> 1';
::is scalar do {"OverloadExample" ~~ Overload['|']}, scalar do{""}, '"OverloadExample" ~~ Overload[\'|\']    # -> ""';

# 
# ## InstanceOf[A...]

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

# The class or the object has the roles.
# 
# The presence of the role is checked by the `does` method.
# 
done_testing; }; subtest 'ConsumerOf[A...]' => sub { 
package NoneExample {}
package RoleExample { sub does { $_[1] ~~ [qw/Role1 Role2/] } }

::is scalar do {'RoleExample' ~~ ConsumerOf[qw/Role1/]}, scalar do{1}, '\'RoleExample\' ~~ ConsumerOf[qw/Role1/] # -> 1';
::is scalar do {'RoleExample' ~~ ConsumerOf[qw/Role2 Role1/]}, scalar do{1}, '\'RoleExample\' ~~ ConsumerOf[qw/Role2 Role1/] # -> 1';
::is scalar do {bless({}, 'RoleExample') ~~ ConsumerOf[qw/Role3 Role2 Role1/]}, scalar do{""}, 'bless({}, \'RoleExample\') ~~ ConsumerOf[qw/Role3 Role2 Role1/] # -> ""';

::is scalar do {'NoneExample' ~~ ConsumerOf[qw/Role1/]}, scalar do{""}, '\'NoneExample\' ~~ ConsumerOf[qw/Role1/]	# -> ""';

# 
# ## StrLike
# 
# String or object with overloaded operator `""`.
# 
done_testing; }; subtest 'StrLike' => sub { 
::is scalar do {"" ~~ StrLike}, scalar do{1}, '"" ~~ StrLike    							# -> 1';

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

::is scalar do {bless({}, "StrLikeExample") ~~ StrLike}, scalar do{1}, 'bless({}, "StrLikeExample") ~~ StrLike    	# -> 1';

::is scalar do {{} ~~ StrLike}, scalar do{""}, '{} ~~ StrLike    							# -> ""';

# 
# ## RegexpLike
# 
# The regular expression or the object with overloaded operator `qr`.
# 
done_testing; }; subtest 'RegexpLike' => sub { 
::is scalar do {ref(qr//)}, "Regexp", 'ref(qr//)  # => Regexp';
::is scalar do {Scalar::Util::reftype(qr//)}, "REGEXP", 'Scalar::Util::reftype(qr//)  # => REGEXP';

my $regex = bless qr//, "A";
::is scalar do {Scalar::Util::reftype($regex)}, "REGEXP", 'Scalar::Util::reftype($regex) # => REGEXP';

::is scalar do {$regex ~~ RegexpLike}, scalar do{1}, '$regex ~~ RegexpLike    # -> 1';
::is scalar do {qr// ~~ RegexpLike}, scalar do{1}, 'qr// ~~ RegexpLike    	# -> 1';
::is scalar do {"" ~~ RegexpLike}, scalar do{""}, '"" ~~ RegexpLike    	# -> ""';

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

::is scalar do {"RegexpLikeExample" ~~ RegexpLike}, scalar do{""}, '"RegexpLikeExample" ~~ RegexpLike    # -> ""';
::is scalar do {bless({}, "RegexpLikeExample") ~~ RegexpLike}, scalar do{1}, 'bless({}, "RegexpLikeExample") ~~ RegexpLike    # -> 1';

# 
# ## CodeLike
# 
# The subroutines.
# 
done_testing; }; subtest 'CodeLike' => sub { 
::is scalar do {sub {} ~~ CodeLike}, scalar do{1}, 'sub {} ~~ CodeLike    	# -> 1';
::is scalar do {\&CodeLike ~~ CodeLike}, scalar do{1}, '\&CodeLike ~~ CodeLike  # -> 1';
::is scalar do {{} ~~ CodeLike}, scalar do{""}, '{} ~~ CodeLike  		# -> ""';

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

::is scalar do {{} ~~ ArrayLike[Int]}, scalar do{""}, '{} ~~ ArrayLike[Int]    # -> ""';

::is scalar do {[] ~~ ArrayLike}, scalar do{1}, '[] ~~ ArrayLike    	# -> 1';

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

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

::is scalar do {$x ~~ ArrayLike}, scalar do{1}, '$x ~~ ArrayLike    # -> 1';

::is scalar do {$x ~~ ArrayLike[Int]}, scalar do{""}, '$x ~~ ArrayLike[Int]    # -> ""';

$x->[0] = 13;
::is scalar do {$x ~~ ArrayLike[Int]}, scalar do{1}, '$x ~~ ArrayLike[Int]    # -> 1';

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

::is scalar do {{} ~~ HashLike}, scalar do{1}, '{} ~~ HashLike    	# -> 1';
::is scalar do {[] ~~ HashLike}, scalar do{""}, '[] ~~ HashLike    	# -> ""';
::is scalar do {[] ~~ HashLike[Int]}, scalar do{""}, '[] ~~ HashLike[Int] # -> ""';

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

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

::is scalar do {$x ~~ HashLike}, scalar do{1}, '$x ~~ HashLike    	   # -> 1';
::is scalar do {$x ~~ HashLike[Int]}, scalar do{""}, '$x ~~ HashLike[Int]    # -> ""';
::is scalar do {$x ~~ HashLike[Num]}, scalar do{1}, '$x ~~ HashLike[Num]    # -> 1';

# 
# # AUTHOR
# 



( run in 0.762 second using v1.01-cache-2.11-cpan-de7293f3b23 )