Aion
view release on metacpan or search on metacpan
lib/Aion/Type.pm view on Meta::CPAN
use overload
"fallback" => 1,
"&{}" => sub {
my ($self) = @_;
sub { $self->test }
}, # ЧÑÐ¾Ð±Ñ Ñип мог бÑÑÑ Ð²Ñполнен, как ÑÑнкÑиÑ
'""' => "stringify", # ÐÑобÑажаÑÑ Ñип в ÑÑейÑбеке в ÑÑÑоковом пÑедÑÑавлении
"|" => sub {
my ($type1, $type2) = @_;
__PACKAGE__->new(name => "Union", args => [$type1, $type2], test => sub { $type1->test || $type2->test });
},
"&" => sub {
my ($type1, $type2) = @_;
__PACKAGE__->new(name => "Intersection", args => [$type1, $type2], test => sub { $type1->test && $type2->test });
},
"~" => sub {
my ($type1) = @_;
__PACKAGE__->new(name => "Exclude", args => [$type1], test => sub { !$type1->test });
},
"~~" => "include",
"eq" => "equal",
"ne" => "nonequal",
">>" => "coerce",
;
Aion::Meta::Util::create_getters(qw/name args as me/);
Aion::Meta::Util::create_accessors(qw/message/);
$Aion::Type::SELF = {
A => __PACKAGE__->new(name => "Argument_A"),
B => __PACKAGE__->new(name => "Argument_B"),
C => __PACKAGE__->new(name => "Argument_C"),
D => __PACKAGE__->new(name => "Argument_D"),
N => __PACKAGE__->new(name => "Argument_N"),
M => __PACKAGE__->new(name => "Argument_M"),
};
# конÑÑÑÑкÑоÑ
# * name (Str) â ÐÐ¼Ñ Ñипа.
# * as (Object[Aion::Type]) â наÑледÑемÑй Ñип.
# * args (ArrayRef) â СпиÑок аÑгÑменÑов.
# * init (CodeRef) â ÐниÑиализаÑÐ¾Ñ Ñипа.
# * 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($_)
} @{$self->{args}};
$self->{name} eq "Union"? join "", "( ", join(" | ", @args), " )":
$self->{name} eq "Intersection"? join "", "( ", join(" & ", @args), " )":
$self->{name} eq "Exclude"? (
@args == 1? join "", "~", @args:
join "", "~( ", join(" | ", @args), " )"
):
join("", $self->{name}, @args? ("[", join(", ", @args), "]") : ());
}
sub equal {
my ($self, $type) = @_;
return 1 if Scalar::Util::refaddr $self == Scalar::Util::refaddr $type;
return "" unless UNIVERSAL::isa($type, __PACKAGE__);
return "" unless $self->{name} eq $type->{name};
return "" unless @{$self->{args}} == @{$type->{args}};
return "" unless $self->{as} && $self->{as}->equal($type->{as})
|| !$self->{as} && !$type->{as};
my $i = 0;
for my $arg (@{$self->{args}}) {
return "" unless $arg eq $type->{args}[$i++];
}
return 1;
}
sub nonequal {
my ($self, $type) = @_;
!$self->equal($type)
}
# ТеÑÑиÑоваÑÑ Ð·Ð½Ð°Ñение в $_
sub test {
my ($self) = @_;
local $Aion::Type::SELF = $self;
my $ok = $self->{test}->();
$ok
}
# ÐниÑиализиÑоваÑÑ Ñип
sub init {
my ($self) = @_;
local $Aion::Type::SELF = $self;
$self->{init}->();
$self
}
# ЯвлÑеÑÑÑ ÑлеменÑом множеÑÑва опиÑÑваемого Ñипом
sub include {
(my $self, local $_) = @_;
$self->test
}
# Ðе ÑвлÑеÑÑÑ ÑлеменÑом множеÑÑва опиÑÑваемого Ñипом
( run in 0.961 second using v1.01-cache-2.11-cpan-437f7b0c052 )