Aion
view release on metacpan or search on metacpan
lib/Aion/Types.pm view on Meta::CPAN
package Aion::Types;
# ТипÑ-валидаÑоÑÑ Ð´Ð»Ñ Aion
use common::sense;
use warnings FATAL => 'recursion';
use Aion::Meta::Util qw/subref_is_reachable val_to_str/;
use Aion::Type;
use Aion::Type::Lim;
use List::Util qw/all any first/;
use Exporter qw/import/;
require overload;
use POSIX qw//;
use Scalar::Util qw/looks_like_number reftype refaddr blessed/;
use Sub::Util qw//;
our @EXPORT = our @EXPORT_OK = grep {
eval {*{$Aion::Types::{$_}}{CODE}} && !/^(_|(NaN|import|all|any|first|looks_like_number|reftype|refaddr|blessed|subref_is_reachable|val_to_str|DBL_MAX)\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 {
my ($pkg, $referent, $data) = @_;
my $subname = Sub::Util::subname $referent;
$subname =~ s/^.*:://;
die "Anonymous subroutine cannot use :Isa!" if $subname eq '__ANON__';
my @signature = eval "package $pkg; map { UNIVERSAL::isa(\$_, 'Aion::Type')? \$_: __PACKAGE__->can(\$_)? __PACKAGE__->can(\$_)->(): Aion::Types::External([\$_]) } ($data)";
die if $@;
die "$pkg\::$subname has no return type!" if @signature == 0;
require Aion::Meta::Subroutine;
my $subroutine = Aion::Meta::Subroutine->new(
pkg => $pkg,
subname => $subname,
signature => \@signature,
referent => $referent,
);
if(!subref_is_reachable($referent)) {
$Aion::META{$pkg}{require}{$subname} = $subroutine;
} else {
my $require = delete $Aion::META{$pkg}{require}{$subname};
$require->compare($subroutine) if $require;
my $overload = $Aion::META{$pkg}{subroutine}{$subname};
$overload->compare($subroutine) if $overload;
$subroutine->wrap_sub;
}
}
BEGIN {
my $INIT_ARGS = sub { @{&ARGS} = map External([$_]), &ARGS };
my $INIT_KW_ARGS = sub { @{&ARGS} = List::Util::pairmap { $a => External([$b]) } &ARGS };
my $COMBINE_SUBS = sub {
my ($f1, $f2) = @_;
sub { $f1->(); $f2->() }
};
my $COMBINE_WHERE = sub {
my ($f1, $f2) = @_;
sub { $f1->() && $f2->() }
};
my $IS_PARAM = sub {
my @S = @_;
while(@S) {
my $arg = pop @S;
lib/Aion/Types.pm view on Meta::CPAN
" <html1>" ~~ Html # -> ""
=head2 StrDate
Date in C<yyyy-mm-dd> format.
"2001-01-12" ~~ StrDate # -> 1
"01-01-01" ~~ StrDate # -> ""
=head2 StrDateTime
Date and time in the format C<yyyy-mm-dd HH:MM:SS>.
"2012-12-01 00:00:00" ~~ StrDateTime # -> 1
"2012-12-01 00:00:00 " ~~ StrDateTime # -> ""
=head2 StrMatch[regexp]
Matches a string against a regular expression.
' abc ' ~~ StrMatch[qr/abc/] # -> 1
' abbc ' ~~ StrMatch[qr/abc/] # -> ""
=head2 ClassName
The class name is a package with a C<new> method.
'Aion::Type' ~~ ClassName # -> 1
'Aion::Types' ~~ ClassName # -> ""
=head2 RoleName
The role name is a package without the C<new> method, with C<@ISA>, or with any one method.
package ExRole1 {
sub any_method {}
}
package ExRole2 {
our @ISA = qw/ExRole1/;
}
'ExRole1' ~~ RoleName # -> 1
'ExRole2' ~~ RoleName # -> 1
'Aion::Type' ~~ RoleName # -> ""
'Nouname::Empty::Package' ~~ RoleName # -> ""
=head2 StrRat
String representation of rational numbers.
Since in perl rational numbers are supported using the C<bigrat> pragma, which turns all rational numbers into C<Math::BigRat>, it is used in a ghost to C<Rat>.
"6/7" ~~ StrRat # -> 1
"-6/7" ~~ StrRat # -> 1
"+6/7" ~~ StrRat # -> 1
6 ~~ StrRat # -> 1
"inf" ~~ StrRat # -> 1
"+Inf" ~~ StrRat # -> 1
"NaN" ~~ StrRat # -> 1
"-nan" ~~ StrRat # -> 1
6.5 ~~ StrRat # -> 1
"6.5 " ~~ StrRat # -> ''
=head2 Rat
Rational numbers. Short for C<Object['Math::BigRat']>. Has a ghost.
use Math::BigRat;
use Math::BigFloat;
use Math::BigInt;
"6/7" ~~ Rat # -> ""
Math::BigRat->new("6/7") ~~ Rat # -> 1
=head2 Num
Numbers.
-6.5 ~~ Num # -> 1
6.5e-7 ~~ Num # -> 1
"6.5 " ~~ Num # -> ""
=head2 PositiveNum
Positive numbers.
0 ~~ PositiveNum # -> 1
0.1 ~~ PositiveNum # -> 1
-0.1 ~~ PositiveNum # -> ""
-0 ~~ PositiveNum # -> 1
=head2 Int
Whole numbers.
123 ~~ Int # -> 1
-12 ~~ Int # -> 1
5.5 ~~ Int # -> ""
=head2 Nat
Integers 1+.
0 ~~ Nat # -> ""
1 ~~ Nat # -> 1
Nat->instanceof('Range') # -> 1
Nat->instanceof('Int') # -> 1
Nat <= Range[1, 'Inf'] # -> 1
Nat <= Range[2, 'Inf'] # -> ""
Nat <= Range[-100, 'Inf'] # -> 1
=head2 PositiveInt
Positive integers.
+0 ~~ PositiveInt # -> 1
-0 ~~ PositiveInt # -> 1
( run in 1.506 second using v1.01-cache-2.11-cpan-9581c071862 )