view release on metacpan or search on metacpan
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
i18n/Aion/Types.ru-en.po view on Meta::CPAN
msgid "ÐодпÑогÑамма Ñ Ñелом."
msgstr "Subroutine with body."
msgid "ÐодпÑогÑамма без Ñела."
msgstr "Subroutine without body."
msgid "СÑÑлка на подпÑогÑÐ°Ð¼Ð¼Ñ Ñ ÑооÑвеÑÑÑвÑÑÑей ÑигнаÑÑÑой."
msgstr "A link to a subroutine with the corresponding signature."
msgid "ÐодпÑогÑÐ°Ð¼Ð¼Ñ Ð±ÐµÐ· Ñела не обоÑаÑиваÑÑÑÑ Ð² обÑабоÑÑик ÑигнаÑÑÑÑ, а ÑигнаÑÑÑа запоминаеÑÑÑ Ð´Ð»Ñ Ð²Ð°Ð»Ð¸Ð´Ð°Ñии ÑооÑвеÑÑÑÐ²Ð¸Ñ Ð²Ð¿Ð¾ÑледÑÑвии оÐ...
msgstr "Subroutines without a body are not wrapped in a signature handler, and the signature is remembered to validate the conformity of a subsequently declared subroutine with a body. Therefore the function has no signature."
msgid "РегÑлÑÑное вÑÑажение."
msgstr "Regular expression."
msgid "СÑÑлка на ÑкалÑÑ Ð¸Ð»Ð¸ ÑÑÑлка на ÑÑÑлкÑ."
msgstr "A reference to a scalar or a reference to a reference."
msgid "СÑÑлка на ÑкалÑÑ."
msgstr "Reference to a scalar."
lib/Aion.pm view on Meta::CPAN
}
# isa => Type
sub isa_aspect {
my ($isa, $feature) = @_;
my ($construct, $name) = @$feature{qw/construct name/};
die "has: $name - isa maybe Aion::Type" unless UNIVERSAL::isa($isa, 'Aion::Type');
$feature->{isa} = $isa;
$construct->add_release("${\$feature->meta}\{isa}->validate(\$val, 'Get feature $name');") if ISA =~ /ro|rw/;
$construct->add_preset("${\$feature->meta}\{isa}->validate(\$val, 'Set feature $name');") if ISA =~ /wo|rw/;
}
# coerce => 1
sub coerce_aspect {
my ($coerce, $feature) = @_;
return unless $coerce;
die "coerce: isa not present!" unless $feature->{isa};
lib/Aion.pm view on Meta::CPAN
sub default_aspect {
my ($default, $feature) = @_;
my $name = $feature->name;
my $default_is_code = ref $default eq "CODE";
if($default_is_code) {
$feature->{builder} = $default;
} else {
$feature->{default} = $default;
$feature->{opt}{isa}->validate($default, $name) if $feature->{opt}{isa};
}
if($feature->{opt}{lazy} // $default_is_code) {
$feature->{lazy} = 1;
if ($default_is_code) {
$feature->construct->add_access("unless(%(has)s) {
my \$val = ${\$feature->meta}\{builder}->(\$self);
%(write)s
}");
lib/Aion/Meta/Subroutine.pm view on Meta::CPAN
my $return_of_meth = "Return of method `$subname`";
my @signature = @$signature;
my $ret = pop @signature;
my ($ret_array, $ret_scalar) = exists $ret->{is_wantarray}? @{$ret->{args}}: (Tuple([$ret]), $ret);
my $args = Tuple(\@signature);
my $sub = sub {
$args->validate(\@_, $args_of_meth);
wantarray? do {
my @returns = $referent->(@_);
$ret_array->validate(\@returns, $returns_of_meth);
@returns
}: do {
my $return = $referent->(@_);
$ret_scalar->validate($return, $return_of_meth);
$return
}
};
Sub::Util::set_prototype Sub::Util::prototype($referent), $sub;
Sub::Util::set_subname Sub::Util::subname($referent), $sub;
*{"$pkg\::$subname"} = $sub if $subname ne '__ANON__';
$self->{wrapsub} = $sub;
lib/Aion/Type.md view on Meta::CPAN
"a" ~~ $IntOrChar # => 1
"ab" ~~ $IntOrChar # -> ""
my $Digit = $Int & $Char;
7 ~~ $Digit # => 1
77 ~~ $Digit # -> ""
"a" ~~ ~$Int; # => 1
5 ~~ ~$Int; # -> ""
eval { $Int->validate("a", "..Eval..") }; $@ # ~> ..Eval.. must have the type Int. The it is 'a'
```
# DESCRIPTION
ÐоÑÐ¾Ð¶Ð´Ð°ÐµÑ Ð²Ð°Ð»Ð¸Ð´Ð°ÑоÑÑ. ÐÑполÑзÑеÑÑÑ Ð² `Aion::Types::subtype`.
# METHODS
## new (%ARGUMENTS)
lib/Aion/Type.md view on Meta::CPAN
my $Num = Aion::Type->new(name => "Num", message => sub {
"Error: $_ is'nt $Aion::Type::SELF->{N}!"
});
$Num->detail("x", "car") # => Error: x is'nt car!
```
`$Aion::Type::SELF->{N}` equivalent to `N` in context of `Aion::Types`.
## validate ($element, $feature)
ÐÑовеÑÑÐµÑ `$element` и вÑбÑаÑÑÐ²Ð°ÐµÑ ÑообÑение `detail`, еÑли ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð½Ðµ пÑÐ¸Ð½Ð°Ð´Ð»ÐµÐ¶Ð¸Ñ ÐºÐ»Ð°ÑÑÑ.
```perl
my $PositiveInt = Aion::Type->new(
name => "PositiveInt",
test => sub { /^\d+$/ },
);
eval {
$PositiveInt->validate(-1, "Neg")
};
$@ # ~> Neg must have the type PositiveInt. The it is -1
```
## val_to_str ($val)
ÐеÑÐµÐ²Ð¾Ð´Ð¸Ñ `$val` в ÑÑÑокÑ.
```perl
Aion::Type->new->val_to_str([1,2,{x=>6}]) # => [1, 2, {x => 6}]
lib/Aion/Type.pm view on Meta::CPAN
(my $self, local $_, my $name) = @_;
local $Aion::Type::SELF = $self;
local $Aion::Type::SELF->{N} = $name;
$self->{message}? $self->{message}->():
"$name must have the type $self. The it is ${\
Aion::Meta::Util::val_to_str($_)
}!"
}
# ÐалидиÑоваÑÑ Ð·Ð½Ð°Ñение в паÑамеÑÑе
sub validate {
(my $self, local $_, my $name) = @_;
die $self->detail($_, $name) if !$self->test;
$_
}
# ÐÑеобÑазоваÑÑ Ð·Ð½Ð°Ñение в ÑÑÑокÑ
sub val_to_str {
my ($self, $val) = @_;
Aion::Meta::Util::val_to_str($val)
}
lib/Aion/Type.pm view on Meta::CPAN
"a" ~~ $IntOrChar # => 1
"ab" ~~ $IntOrChar # -> ""
my $Digit = $Int & $Char;
7 ~~ $Digit # => 1
77 ~~ $Digit # -> ""
"a" ~~ ~$Int; # => 1
5 ~~ ~$Int; # -> ""
eval { $Int->validate("a", "..Eval..") }; $@ # ~> ..Eval.. must have the type Int. The it is 'a'
=head1 DESCRIPTION
Spawns validators. Used in C<Aion::Types::subtype>.
=head1 METHODS
=head2 new (%ARGUMENTS)
Constructor.
lib/Aion/Type.pm view on Meta::CPAN
$Int->detail(-5, "Feature car") # => Feature car must have the type Int. The it is -5!
my $Num = Aion::Type->new(name => "Num", message => sub {
"Error: $_ is'nt $Aion::Type::SELF->{N}!"
});
$Num->detail("x", "car") # => Error: x is'nt car!
C<< $Aion::Type::SELF-E<gt>{N} >> equivalent to C<N> in context of C<Aion::Types>.
=head2 validate ($element, $feature)
Checks C<$element> and throws a C<detail> message if the element does not belong to the class.
my $PositiveInt = Aion::Type->new(
name => "PositiveInt",
test => sub { /^\d+$/ },
);
eval {
$PositiveInt->validate(-1, "Neg")
};
$@ # ~> Neg must have the type PositiveInt. The it is -1
=head2 val_to_str ($val)
Converts C<$val> to a string.
Aion::Type->new->val_to_str([1,2,{x=>6}]) # => [1, 2, {x => 6}]
=head2 instanceof ($type)
lib/Aion/Types.md view on Meta::CPAN
use Aion::Types;
BEGIN {
subtype SpeakOfKitty => as StrMatch[qr/\bkitty\b/i],
message { "Speak is'nt included kitty!" };
}
"Kitty!" ~~ SpeakOfKitty # -> 1
"abc" ~~ SpeakOfKitty # -> ""
SpeakOfKitty->validate("abc", "This") # @-> Speak is'nt included kitty!
BEGIN {
subtype IntOrArrayRef => as (Int | ArrayRef);
}
[] ~~ IntOrArrayRef # -> 1
35 ~~ IntOrArrayRef # -> 1
"" ~~ IntOrArrayRef # -> ""
lib/Aion/Types.md view on Meta::CPAN
СоздаÑÑ Ð½Ð¾Ð²Ñй Ñип.
```perl
BEGIN {
subtype One => where { $_ == 1 } message { "Actual 1 only!" };
}
1 ~~ One # -> 1
0 ~~ One # -> ""
eval { One->validate(0) }; $@ # ~> Actual 1 only!
```
`where` и `message` â ÑÑо ÑинÑакÑиÑеÑкий ÑаÑ
аÑ, а `subtype` можно иÑполÑзоваÑÑ Ð±ÐµÐ· ниÑ
.
```perl
BEGIN {
subtype Many => (where => sub { $_ > 1 });
}
2 ~~ Many # -> 1
lib/Aion/Types.md view on Meta::CPAN
ÐÑполÑзÑеÑÑÑ Ñ `subtype` Ð´Ð»Ñ ÑаÑÑиÑÐµÐ½Ð¸Ñ Ñоздаваемого Ñипа `$super_type`.
## init_where ($code)
ÐниÑиализиÑÑÐµÑ Ñип Ñ Ð½Ð¾Ð²Ñми аÑгÑменÑами. ÐÑполÑзÑеÑÑÑ Ñ `subtype`.
```perl
BEGIN {
subtype 'LessThen[A]',
init_where { Num->validate(A, "Argument LessThen[A]") }
where { $_ < A };
}
eval { LessThen["string"] }; $@ # ~> Argument LessThen\[A\]
5 ~~ LessThen[5] # -> ""
```
## where ($code)
lib/Aion/Types.pm view on Meta::CPAN
subtype "Control", as &Any;
subtype "Union[A, B...]", as &Control,
where { my $val = $_; any { $_->include($val) } ARGS };
subtype "Intersection[A, B...]", as &Control,
where { my $val = $_; all { $_->include($val) } ARGS };
subtype "Exclude[A, B...]", as &Control,
where { my $val = $_; !any { $_->include($val) } ARGS };
subtype "Option[A]", as &Control,
init_where {
SELF->{is_option} = 1;
Tuple([Object(["Aion::Type"])])->validate(scalar ARGS, "Arguments Option[A]")
}
where { A->test };
subtype "Wantarray[A, S]", as &Control,
init_where {
SELF->{is_wantarray} = 1;
Tuple([Object(["Aion::Type"]), Object(["Aion::Type"])])->validate(scalar ARGS, "Arguments Wantarray[A, S]")
}
where { ... };
subtype "Item", as &Any;
subtype "Bool", as &Item, where { ref $_ eq "" and /^(1|0|)\z/ };
subtype "BoolLike", as &Item, where {
return 1 if overload::Method($_, 'bool');
my $m = overload::Method($_, '0+');
Bool()->include($m ? $m->($_) : $_) };
lib/Aion/Types.pm view on Meta::CPAN
where {
my ($K, $V) = ARGS;
while(my ($k, $v) = each %$_) {
return "" unless $K->include($k) && $V->include($v);
}
return 1;
};
my $tuple_args = ArrayRef([Object(['Aion::Type'])]);
subtype "Tuple[A...]", as &ArrayRef,
init_where { $tuple_args->validate(scalar ARGS, "Arguments Tuple[A...]") }
where {
my $k = 0;
for my $A (ARGS) {
return "" if $A->exclude($_->[$k++]);
}
$k == @$_
};
subtype "CycleTuple[A...]", as &ArrayRef,
init_where { $tuple_args->validate(scalar ARGS, "Arguments CycleTuple[A...]") }
where {
my $k = 0;
while($k < @$_) {
for my $A (ARGS) {
return "" if $A->exclude($_->[$k++]);
}
}
$k == @$_
};
my $dict_args = CycleTuple([&Str, Object(['Aion::Type'])]);
subtype "Dict[k => A, ...]", as &HashRef,
init_where { $dict_args->validate(scalar ARGS, "Arguments Dict[k => A, ...]") }
where {
my $count = 0; my $k;
for my $A (ARGS) {
$k = $A, next unless ref $A;
if(exists $_->{$k}) {
return "" if $A->exclude($_->{$k});
$count++;
} else {
return "" if !exists $A->{is_option};
}
lib/Aion/Types.pm view on Meta::CPAN
use Aion::Types;
BEGIN {
subtype SpeakOfKitty => as StrMatch[qr/\bkitty\b/i],
message { "Speak is'nt included kitty!" };
}
"Kitty!" ~~ SpeakOfKitty # -> 1
"abc" ~~ SpeakOfKitty # -> ""
SpeakOfKitty->validate("abc", "This") # @-> Speak is'nt included kitty!
BEGIN {
subtype IntOrArrayRef => as (Int | ArrayRef);
}
[] ~~ IntOrArrayRef # -> 1
35 ~~ IntOrArrayRef # -> 1
"" ~~ IntOrArrayRef # -> ""
lib/Aion/Types.pm view on Meta::CPAN
=head2 subtype ($name, @paraphernalia)
Creates a new type.
BEGIN {
subtype One => where { $_ == 1 } message { "Actual 1 only!" };
}
1 ~~ One # -> 1
0 ~~ One # -> ""
eval { One->validate(0) }; $@ # ~> Actual 1 only!
C<where> and C<message> are syntactic sugar, and C<subtype> can be used without them.
BEGIN {
subtype Many => (where => sub { $_ > 1 });
}
2 ~~ Many # -> 1
eval { subtype Many => (where1 => sub { $_ > 1 }) }; $@ # ~> subtype Many unused keys left: where1
lib/Aion/Types.pm view on Meta::CPAN
=head2 as ($super_type)
Used with C<subtype> to extend the created C<$super_type> type.
=head2 init_where ($code)
Initializes a type with new arguments. Used with C<subtype>.
BEGIN {
subtype 'LessThen[A]',
init_where { Num->validate(A, "Argument LessThen[A]") }
where { $_ < A };
}
eval { LessThen["string"] }; $@ # ~> Argument LessThen\[A\]
5 ~~ LessThen[5] # -> ""
=head2 where ($code)
Uses C<$code> as a test. The value for the test is passed to C<$_>.
lib/Aion/Types.pm view on Meta::CPAN
=head2 Isa[A...]
A link to a subroutine with the corresponding signature.
sub sig_ex :Isa(Int => Str) {}
\&sig_ex ~~ Isa[Int => Str] # -> 1
\&sig_ex ~~ Isa[Int => Str => Num] # -> ""
\&sig_ex ~~ Isa[Int => Num] # -> ""
Subroutines without a body are not wrapped in a signature handler, and the signature is remembered to validate the conformity of a subsequently declared subroutine with a body. Therefore the function has no signature.
sub unreachable_sig_ex :Isa(Int => Str);
\&unreachable_sig_ex ~~ Isa[Int => Str] # -> ""
=head2 RegexpRef
Regular expression.
qr// ~~ RegexpRef # -> 1
t/aion/type.t view on Meta::CPAN
::is scalar do {"a" ~~ $IntOrChar}, "1", '"a" ~~ $IntOrChar # => 1';
::is scalar do {"ab" ~~ $IntOrChar}, scalar do{""}, '"ab" ~~ $IntOrChar # -> ""';
my $Digit = $Int & $Char;
::is scalar do {7 ~~ $Digit}, "1", '7 ~~ $Digit # => 1';
::is scalar do {77 ~~ $Digit}, scalar do{""}, '77 ~~ $Digit # -> ""';
::is scalar do {"a" ~~ ~$Int;}, "1", '"a" ~~ ~$Int; # => 1';
::is scalar do {5 ~~ ~$Int;}, scalar do{""}, '5 ~~ ~$Int; # -> ""';
::like scalar do {eval { $Int->validate("a", "..Eval..") }; $@}, qr{..Eval.. must have the type Int. The it is 'a'}, 'eval { $Int->validate("a", "..Eval..") }; $@ # ~> ..Eval.. must have the type Int. The it is \'a\'';
#
# # DESCRIPTION
#
# ÐоÑÐ¾Ð¶Ð´Ð°ÐµÑ Ð²Ð°Ð»Ð¸Ð´Ð°ÑоÑÑ. ÐÑполÑзÑеÑÑÑ Ð² `Aion::Types::subtype`.
#
# # METHODS
#
# ## new (%ARGUMENTS)
#
t/aion/type.t view on Meta::CPAN
my $Num = Aion::Type->new(name => "Num", message => sub {
"Error: $_ is'nt $Aion::Type::SELF->{N}!"
});
::is scalar do {$Num->detail("x", "car")}, "Error: x is'nt car!", '$Num->detail("x", "car") # => Error: x is\'nt car!';
#
# `$Aion::Type::SELF->{N}` equivalent to `N` in context of `Aion::Types`.
#
# ## validate ($element, $feature)
#
# ÐÑовеÑÑÐµÑ `$element` и вÑбÑаÑÑÐ²Ð°ÐµÑ ÑообÑение `detail`, еÑли ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð½Ðµ пÑÐ¸Ð½Ð°Ð´Ð»ÐµÐ¶Ð¸Ñ ÐºÐ»Ð°ÑÑÑ.
#
::done_testing; }; subtest 'validate ($element, $feature)' => sub {
my $PositiveInt = Aion::Type->new(
name => "PositiveInt",
test => sub { /^\d+$/ },
);
eval {
$PositiveInt->validate(-1, "Neg")
};
::like scalar do {$@}, qr{Neg must have the type PositiveInt. The it is -1}, '$@ # ~> Neg must have the type PositiveInt. The it is -1';
#
# ## val_to_str ($val)
#
# ÐеÑÐµÐ²Ð¾Ð´Ð¸Ñ `$val` в ÑÑÑокÑ.
#
::done_testing; }; subtest 'val_to_str ($val)' => sub {
::is scalar do {Aion::Type->new->val_to_str([1,2,{x=>6}])}, "[1, 2, {x => 6}]", 'Aion::Type->new->val_to_str([1,2,{x=>6}]) # => [1, 2, {x => 6}]';
t/aion/types.t view on Meta::CPAN
use Aion::Types;
BEGIN {
subtype SpeakOfKitty => as StrMatch[qr/\bkitty\b/i],
message { "Speak is'nt included kitty!" };
}
::is scalar do {"Kitty!" ~~ SpeakOfKitty}, scalar do{1}, '"Kitty!" ~~ SpeakOfKitty # -> 1';
::is scalar do {"abc" ~~ SpeakOfKitty}, scalar do{""}, '"abc" ~~ SpeakOfKitty # -> ""';
eval {SpeakOfKitty->validate("abc", "This")}; ok defined($@), 'SpeakOfKitty->validate("abc", "This") # @-> Speak is\'nt included kitty!'; ::cmp_ok $@, '=~', '^' . quotemeta 'Speak is\'nt included kitty!', 'SpeakOfKitty->validate("abc", "This") # @-> ...
BEGIN {
subtype IntOrArrayRef => as (Int | ArrayRef);
}
::is scalar do {[] ~~ IntOrArrayRef}, scalar do{1}, '[] ~~ IntOrArrayRef # -> 1';
::is scalar do {35 ~~ IntOrArrayRef}, scalar do{1}, '35 ~~ IntOrArrayRef # -> 1';
::is scalar do {"" ~~ IntOrArrayRef}, scalar do{""}, '"" ~~ IntOrArrayRef # -> ""';
t/aion/types.t view on Meta::CPAN
#
# СоздаÑÑ Ð½Ð¾Ð²Ñй Ñип.
#
::done_testing; }; subtest 'subtype ($name, @paraphernalia)' => sub {
BEGIN {
subtype One => where { $_ == 1 } message { "Actual 1 only!" };
}
::is scalar do {1 ~~ One}, scalar do{1}, '1 ~~ One # -> 1';
::is scalar do {0 ~~ One}, scalar do{""}, '0 ~~ One # -> ""';
::like scalar do {eval { One->validate(0) }; $@}, qr{Actual 1 only\!}, 'eval { One->validate(0) }; $@ # ~> Actual 1 only!';
#
# `where` и `message` â ÑÑо ÑинÑакÑиÑеÑкий ÑаÑ
аÑ, а `subtype` можно иÑполÑзоваÑÑ Ð±ÐµÐ· ниÑ
.
#
BEGIN {
subtype Many => (where => sub { $_ > 1 });
}
::is scalar do {2 ~~ Many}, scalar do{1}, '2 ~~ Many # -> 1';
t/aion/types.t view on Meta::CPAN
#
# ÐÑполÑзÑеÑÑÑ Ñ `subtype` Ð´Ð»Ñ ÑаÑÑиÑÐµÐ½Ð¸Ñ Ñоздаваемого Ñипа `$super_type`.
#
# ## init_where ($code)
#
# ÐниÑиализиÑÑÐµÑ Ñип Ñ Ð½Ð¾Ð²Ñми аÑгÑменÑами. ÐÑполÑзÑеÑÑÑ Ñ `subtype`.
#
::done_testing; }; subtest 'init_where ($code)' => sub {
BEGIN {
subtype 'LessThen[A]',
init_where { Num->validate(A, "Argument LessThen[A]") }
where { $_ < A };
}
::like scalar do {eval { LessThen["string"] }; $@}, qr{Argument LessThen\[A\]}, 'eval { LessThen["string"] }; $@ # ~> Argument LessThen\[A\]';
::is scalar do {5 ~~ LessThen[5]}, scalar do{""}, '5 ~~ LessThen[5] # -> ""';
#
# ## where ($code)
#