Aion
view release on metacpan or search on metacpan
use common::sense; use open qw/:std :utf8/; use Carp qw//; use Cwd 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; use String::Diff q...
# # NAME
#
# Aion - поÑÑмодеÑниÑÑÑÐºÐ°Ñ Ð¾Ð±ÑекÑÐ½Ð°Ñ ÑиÑÑема Ð´Ð»Ñ Perl 5, ÑÐ°ÐºÐ°Ñ ÐºÐ°Ðº «Mouse», «Moose», «Moo», «Mo» и «M», но Ñ ÑлÑÑÑениÑми
#
# # VERSION
#
# 2.2
#
# # SYNOPSIS
#
subtest 'SYNOPSIS' => sub {
package Calc {
use Aion;
has a => (is => 'ro+', isa => Num);
has b => (is => 'ro+', isa => Num);
has op => (is => 'ro', isa => Enum[qw/+ - * \/ **/], default => '+');
sub result : Isa(Me => Num) {
my ($self) = @_;
eval "${\ $self->a} ${\ $self->op} ${\ $self->b}";
}
}
local ($::_g0 = do {Calc->new(a => 1.1, b => 2)->result}, $::_e0 = "3.1"); ::ok $::_g0 eq $::_e0, 'Calc->new(a => 1.1, b => 2)->result # => 3.1' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
#
# # DESCRIPTION
#
# Aion â ÐÐÐ-ÑÑеймвоÑк Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÐºÐ»Ð°ÑÑов Ñ **ÑиÑами**, Ð¸Ð¼ÐµÐµÑ **аÑпекÑÑ**, **Ñоли** и Ñак далее.
#
# СвойÑÑва, обÑÑвленнÑе ÑеÑез has, назÑваÑÑÑÑ **ÑиÑами**.
#
# Ð `is`, `isa`, `default` и Ñак далее в `has` назÑваÑÑÑÑ **аÑпекÑами**.
#
# Ðомимо ÑÑандаÑÑнÑÑ
аÑпекÑов, Ñоли могÑÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÑÑÑ Ñвои ÑобÑÑвеннÑе аÑпекÑÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð¿Ð¾Ð´Ð¿ÑогÑÐ°Ð¼Ð¼Ñ **aspect**.
#
# СигнаÑÑÑа меÑодов Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑовеÑÑÑÑÑÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð°ÑÑибÑÑа `:Isa(...)`.
#
# # SUBROUTINES IN CLASSES AND ROLES
#
# `use Aion` импоÑÑиÑÑÐµÑ ÑÐ¸Ð¿Ñ Ð¸Ð· модÑÐ»Ñ `Aion::Types` и ÑледÑÑÑие подпÑогÑаммÑ:
#
# ## has ($name, %aspects)
#
# СоздаÑÑ Ð¼ÐµÑод Ð´Ð»Ñ Ð¿Ð¾Ð»ÑÑениÑ/ÑÑÑановки ÑÑнкÑии (ÑвойÑÑва) клаÑÑа.
#
# Файл lib/Animal.pm:
#@> lib/Animal.pm
#>> package Animal;
#>> use Aion;
#>>
#>> has type => (is => 'ro+', isa => Str);
#>> has name => (is => 'rw-', isa => Str, default => 'murka');
#>>
#>> 1;
#@< EOF
#
::done_testing; }; subtest 'has ($name, %aspects)' => sub {
use lib "lib";
use Animal;
my $cat = Animal->new(type => 'cat');
local ($::_g0 = do {$cat->type}, $::_e0 = "cat"); ::ok $::_g0 eq $::_e0, '$cat->type # => cat' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {$cat->name}, $::_e0 = "murka"); ::ok $::_g0 eq $::_e0, '$cat->name # => murka' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
$cat->name("murzik");
local ($::_g0 = do {$cat->name}, $::_e0 = "murzik"); ::ok $::_g0 eq $::_e0, '$cat->name # => murzik' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
#
# ## with
#
# ÐобавлÑÐµÑ Ð² модÑÐ»Ñ Ñоли. ÐÐ»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ Ñоли вÑзÑваеÑÑÑ Ð¼ÐµÑод `import_with`.
#
# Файл lib/Role/Keys/Stringify.pm:
#@> lib/Role/Keys/Stringify.pm
#>> package Role::Keys::Stringify;
#>>
#>> use Aion -role;
#>>
#>> sub keysify {
#>> my ($self) = @_;
#>> join ", ", sort keys %$self;
#>> }
#>>
#>> 1;
#@< EOF
#
# Файл lib/Role/Values/Stringify.pm:
#@> lib/Role/Values/Stringify.pm
#>> package Role::Values::Stringify;
#>>
#>> use Aion -role;
#>>
#>> sub valsify {
#>> my ($self) = @_;
#>> join ", ", map $self->{$_}, sort keys %$self;
#>> }
#>>
#>> 1;
#@< EOF
#
# Файл lib/Class/All/Stringify.pm:
#@> lib/Class/All/Stringify.pm
#>> package Class::All::Stringify;
#>>
#>> use Aion;
#>>
#>> with q/Role::Keys::Stringify/;
#>> with q/Role::Values::Stringify/;
#>>
#>> has [qw/key1 key2/] => (is => 'rw', isa => Str);
#>>
#>> 1;
#@< EOF
#
::done_testing; }; subtest 'with' => sub {
use lib "lib";
use Class::All::Stringify;
my $s = Class::All::Stringify->new(key1=>"a", key2=>"b");
local ($::_g0 = do {$s->keysify}, $::_e0 = "key1, key2"); ::ok $::_g0 eq $::_e0, '$s->keysify # => key1, key2' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {$s->valsify}, $::_e0 = "a, b"); ::ok $::_g0 eq $::_e0, '$s->valsify # => a, b' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
#
# ## exactly ($package)
#
# ÐÑовеÑÑеÑ, ÑÑо `$package` â ÑÑо ÑÑпеÑклаÑÑ Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ или Ñам ÑÑÐ¾Ñ ÐºÐ»Ð°ÑÑ.
#
# РеализаÑÐ¸Ñ Ð¼ÐµÑода `isa` Aion не менÑÐµÑ Ð¸ она наÑ
Ð¾Ð´Ð¸Ñ ÐºÐ°Ðº ÑÑпеÑклаÑÑÑ, Ñак и Ñоли (Ñак как и Ñе и дÑÑгие добавлÑÑÑÑÑ Ð² `@ISA` пакеÑа).
#
::done_testing; }; subtest 'exactly ($package)' => sub {
package Ex::X { use Aion; }
package Ex::A { use Aion; extends q/Ex::X/; }
package Ex::B { use Aion; }
package Ex::C { use Aion; extends qw/Ex::A Ex::B/ }
local ($::_g0 = do {Ex::C->exactly("Ex::A")}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'Ex::C->exactly("Ex::A") # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {Ex::C->exactly("Ex::B")}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'Ex::C->exactly("Ex::B") # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {Ex::C->exactly("Ex::X")}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'Ex::C->exactly("Ex::X") # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {Ex::C->exactly("Ex::X1")}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'Ex::C->exactly("Ex::X1") # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {Ex::A->exactly("Ex::X")}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'Ex::A->exactly("Ex::X") # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {Ex::A->exactly("Ex::A")}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'Ex::A->exactly("Ex::A") # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {Ex::X->exactly("Ex::X")}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'Ex::X->exactly("Ex::X") # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
#
# ## does ($package)
#
# ÐÑовеÑÑеÑ, ÑÑо `$package` â ÑÑо ÑолÑ, коÑоÑÐ°Ñ Ð¸ÑполÑзÑеÑÑÑ Ð² клаÑÑе или дÑÑгой Ñоли.
#
::done_testing; }; subtest 'does ($package)' => sub {
package Role::X { use Aion -role; }
package Role::A { use Aion -role; with qw/Role::X/; }
package Role::B { use Aion -role; }
package Ex::Z { use Aion; with qw/Role::A Role::B/; }
local ($::_g0 = do {Ex::Z->does("Role::A")}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'Ex::Z->does("Role::A") # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {Ex::Z->does("Role::B")}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'Ex::Z->does("Role::B") # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {Ex::Z->does("Role::X")}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'Ex::Z->does("Role::X") # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {Role::A->does("Role::X")}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'Role::A->does("Role::X") # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {Role::A->does("Role::X1")}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'Role::A->does("Role::X1") # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {Ex::Z->does("Ex::Z")}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'Ex::Z->does("Ex::Z") # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
#
# ## aspect ($aspect => sub { ... })
#
# ÐобавлÑÐµÑ Ð°ÑÐ¿ÐµÐºÑ Ðº `has` в ÑекÑÑем клаÑÑе и его клаÑÑам-наÑледникам или ÑекÑÑей Ñоли и пÑименÑÑÑим ÐµÑ ÐºÐ»Ð°ÑÑам.
#
::done_testing; }; subtest 'aspect ($aspect => sub { ... })' => sub {
package Example::Earth {
use Aion;
aspect lvalue => sub {
my ($lvalue, $feature) = @_;
return unless $lvalue;
$feature->construct->add_attr(":lvalue");
};
has moon => (is => "rw", lvalue => 1);
}
my $earth = Example::Earth->new;
$earth->moon = "Mars";
local ($::_g0 = do {$earth->moon}, $::_e0 = "Mars"); ::ok $::_g0 eq $::_e0, '$earth->moon # => Mars' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
#
# ÐÑÐ¿ÐµÐºÑ Ð²ÑзÑваеÑÑÑ ÐºÐ°Ð¶Ð´Ñй Ñаз, когда он Ñказан в `has`.
#
# СоздаÑÐµÐ»Ñ Ð°ÑпекÑа Ð¸Ð¼ÐµÐµÑ Ð¿Ð°ÑамеÑÑÑ:
#
# * `$value` â знаÑение аÑпекÑа.
# * `$feature` â меÑаобÑÐµÐºÑ Ð¾Ð¿Ð¸ÑÑваÑÑий ÑиÑÑ (`Aion::Meta::Feature`).
# * `$aspect_name` â наименование аÑпекÑа.
#
package Example::Mars {
use Aion;
aspect lvalue => sub {
my ($value, $feature, $aspect_name) = @_;
local ($::_g0 = do {$value}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, ' $value # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {$aspect_name}, $::_e0 = "lvalue"); ::ok $::_g0 eq $::_e0, ' $aspect_name # => lvalue' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
$feature->construct->add_attr(":lvalue");
};
has moon => (is => "rw", lvalue => 1);
}
#
# ## pleroma ()
#
# ÐозвÑаÑÐ°ÐµÑ Ð»Ð¾ÐºÐ°ÑоÑ.
#
::done_testing; }; subtest 'pleroma ()' => sub {
local ($::_g0 = do {Aion->pleroma->isa('Aion::Pleroma')}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'Aion->pleroma->isa(\'Aion::Pleroma\') # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::...
#
# # SUBROUTINES IN CLASSES
#
# ## extends (@superclasses)
#
# РаÑÑиÑÑÐµÑ ÐºÐ»Ð°ÑÑ Ð´ÑÑгим клаÑÑом/клаÑÑами. Ðн вÑзÑÐ²Ð°ÐµÑ Ð¸Ð· каждого наÑледÑемого клаÑÑа меÑод `import_extends`, еÑли он в нÑм еÑÑÑ.
#
::done_testing; }; subtest 'extends (@superclasses)' => sub {
package World { use Aion;
our $extended_by_this = 0;
sub import_extends {
my ($class, $extends) = @_;
$extended_by_this ++;
local ($::_g0 = do {$class}, $::_e0 = "World"); ::ok $::_g0 eq $::_e0, ' $class # => World' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {$extends}, $::_e0 = "Hello"); ::ok $::_g0 eq $::_e0, ' $extends # => Hello' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
}
}
package Hello { use Aion;
extends q/World/;
local ($::_g0 = do {$World::extended_by_this}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, ' $World::extended_by_this # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
}
local ($::_g0 = do {Hello->isa("World")}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'Hello->isa("World") # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
#
# ## new (%param)
#
# ÐонÑÑÑÑкÑоÑ.
#
# * УÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ `%param` Ð´Ð»Ñ ÑиÑ.
# * ÐÑовеÑÑеÑ, ÑÑо паÑамеÑÑÑ ÑооÑвеÑÑÑвÑÑÑ ÑиÑам.
# * УÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð¿Ð¾ ÑмолÑаниÑ.
#
::done_testing; }; subtest 'new (%param)' => sub {
package NewExample { use Aion;
has x => (is => 'ro', isa => Num);
has y => (is => 'ro+', isa => Num);
has z => (is => 'ro-', isa => Num);
}
eval {NewExample->new(f => 5)}; local ($::_g0 = $@, $::_e0 = 'y required!'); ok defined($::_g0) && $::_g0 =~ /^${\quotemeta $::_e0}/, 'NewExample->new(f => 5) # @-> y required!' or ::diag ::_string_diff($::_g0, $::_e0, 1); undef $::_g0; undef $::_e0;
eval {NewExample->new(f => 5, y => 10)}; local ($::_g0 = $@, $::_e0 = 'f is\'nt feature!'); ok defined($::_g0) && $::_g0 =~ /^${\quotemeta $::_e0}/, 'NewExample->new(f => 5, y => 10) # @-> f is\'nt feature!' or ::diag ::_string_diff($::_g0, $::_e0, 1...
eval {NewExample->new(f => 5, p => 6, y => 10)}; local ($::_g0 = $@, $::_e0 = 'f, p is\'nt features!'); ok defined($::_g0) && $::_g0 =~ /^${\quotemeta $::_e0}/, 'NewExample->new(f => 5, p => 6, y => 10) # @-> f, p is\'nt features!' or ::diag ::_strin...
eval {NewExample->new(z => 10, y => 10)}; local ($::_g0 = $@, $::_e0 = 'z excessive!'); ok defined($::_g0) && $::_g0 =~ /^${\quotemeta $::_e0}/, 'NewExample->new(z => 10, y => 10) # @-> z excessive!' or ::diag ::_string_diff($::_g0, $::_e0, 1); undef...
my $ex = NewExample->new(y => 8);
eval {$ex->x}; local ($::_g0 = $@, $::_e0 = 'Get feature x must have the type Num. The it is undef!'); ok defined($::_g0) && $::_g0 =~ /^${\quotemeta $::_e0}/, '$ex->x # @-> Get feature x must have the type Num. The it is undef!' or ::diag ::_string_...
$ex = NewExample->new(x => 10.1, y => 8);
local ($::_g0 = do {$ex->x}, $::_e0 = do {10.1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$ex->x # -> 10.1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
#
# # SUBROUTINES IN ROLES
#
# ## requires (@subroutine_names)
#
# ÐÑовеÑÑеÑ, ÑÑо в клаÑÑаÑ
, иÑполÑзÑÑÑиÑ
ÑÑÑ ÑолÑ, еÑÑÑ ÑказаннÑе подпÑогÑÐ°Ð¼Ð¼Ñ Ð¸Ð»Ð¸ ÑиÑи.
#
::done_testing; }; subtest 'requires (@subroutine_names)' => sub {
package Role::Alpha { use Aion -role;
requires qw/abc/;
}
package Omega1 { use Aion; with Role::Alpha; }
::like scalar do {eval { Omega1->new }; $@}, qr{Requires abc of Role::Alpha}, 'eval { Omega1->new }; $@ # ~> Requires abc of Role::Alpha'; undef $::_g0; undef $::_e0;
package Omega { use Aion;
with Role::Alpha;
sub abc { "abc" }
}
local ($::_g0 = do {Omega->new->abc}, $::_e0 = "abc"); ::ok $::_g0 eq $::_e0, 'Omega->new->abc # => abc' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
#
# ## req ($name => @aspects)
#
# ÐÑовеÑÑеÑ, ÑÑо в клаÑÑаÑ
, иÑполÑзÑÑÑиÑ
ÑÑÑ ÑолÑ, еÑÑÑ ÑказаннÑе ÑиÑи Ñ ÑказаннÑми аÑпекÑами.
#
::done_testing; }; subtest 'req ($name => @aspects)' => sub {
package Role::Beta { use Aion -role;
req x => (is => 'rw', isa => Num);
}
package Omega2 { use Aion; with Role::Beta; }
::like scalar do {eval { Omega2->new }; $@}, qr{Requires req x => \(is => 'rw', isa => Num\) of Role::Beta}, 'eval { Omega2->new }; $@ # ~> Requires req x => \(is => \'rw\', isa => Num\) of Role::Beta'; undef $::_g0; undef $::_e0;
package Omega3 { use Aion;
with Role::Beta;
has x => (is => 'rw', isa => Num, default => 12);
}
local ($::_g0 = do {Omega3->new->x}, $::_e0 = do {12}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'Omega3->new->x # -> 12' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
#
# ## Ð Ð¾Ð»Ñ Ð½Ð°ÑледÑÐµÑ ÑолÑ
#
# Ð Ð¾Ð»Ñ Ð¼Ð¾Ð¶ÐµÑ Ð½Ð°ÑледоваÑÑ Ð´ÑÑгÑÑ ÑÐ¾Ð»Ñ ÑеÑез `with`. Так можно ÑÑоÑнÑÑÑ Ð¸Ð½ÑеÑÑейÑ: ÑÐ¸Ð¿Ñ ÑÑебÑÑÑиÑ
ÑÑ ÑиÑей (`req`) и меÑодов (`:Isa`) либо оÑÑаÑÑÑÑ ÑаÐ...
#
# Ð Ð¾Ð»Ñ `Role::Animal` ÑÑебÑÐµÑ ÑвойÑÑво `legs` ÑиÑокого Ñипа `Num | Object` и меÑод `sound` Ñ ÑигнаÑÑÑой `(Me => Str)`.
#
::done_testing; }; subtest 'Ð Ð¾Ð»Ñ Ð½Ð°ÑледÑÐµÑ ÑолÑ' => sub {
package Role::Animal { use Aion -role;
req legs => (isa => Num | Object);
sub sound : Isa(Me => Str);
}
#
# Ð Ð¾Ð»Ñ `Role::Bird` наÑледÑÐµÑ `Role::Animal`, но Ð¿Ð¾Ð½Ð¸Ð¶Ð°ÐµÑ Ñип `legs` до `Num`, а ÑигнаÑÑÑÑ Ð¼ÐµÑода `sound` оÑÑавлÑÐµÑ Ð¿Ñежней.
#
package Role::Bird { use Aion -role;
with qw/Role::Animal/;
req legs => (isa => Num);
sub sound : Isa(Me => Str);
}
#
# ÐлаÑÑ `Ex::Sparrow` иÑполÑзÑÐµÑ ÑÐ¾Ð»Ñ `Role::Bird` и ÑеализÑÐµÑ Ð²Ñе ÐµÑ ÑÑебованиÑ.
#
package Ex::Sparrow { use Aion;
with qw/Role::Bird/;
has legs => (is => 'ro', isa => Num, default => 2);
sub sound : Isa(Me => Str) { 'chirp' }
local ($::_g0 = do {Num < (Num | Object)}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, ' Num < (Num | Object) # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
}
my $sparrow = Ex::Sparrow->new;
local ($::_g0 = do {$sparrow->legs}, $::_e0 = "2"); ::ok $::_g0 eq $::_e0, '$sparrow->legs # => 2' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {$sparrow->sound}, $::_e0 = "chirp"); ::ok $::_g0 eq $::_e0, '$sparrow->sound # => chirp' or ::diag ::_string_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
#
# # ASPECTS
#
# `use Aion` вклÑÑÐ°ÐµÑ Ð² модÑÐ»Ñ ÑледÑÑÑие аÑпекÑÑ Ð´Ð»Ñ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð² `has`:
#
# ## is => $permissions
#
# * `ro` â ÑоздаÑÑ ÑолÑко геÑÑеÑ.
# * `wo` â ÑоздаÑÑ ÑолÑко ÑеÑÑеÑ.
# * `rw` â ÑоздаÑÑ Ð³ÐµÑÑÐµÑ Ð¸ ÑеÑÑеÑ.
#
# Ðо ÑмолÑÐ°Ð½Ð¸Ñ â `rw`.
#
# ÐополниÑелÑнÑе ÑазÑеÑениÑ:
#
# * `+` â ÑиÑа обÑзаÑелÑна в паÑамеÑÑаÑ
конÑÑÑÑкÑоÑа. `+` не иÑполÑзÑеÑÑÑ Ñ `-`.
# * `-` â ÑиÑа не Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ ÑÑÑановлена ÑеÑез конÑÑÑÑкÑоÑ. '-' не иÑполÑзÑеÑÑÑ Ñ `+`.
# * `*` â не инкÑеменÑиÑоваÑÑ ÑÑÑÑÑик ÑÑÑлок на знаÑение (пÑимениÑÑ `weaken` к знаÑÐµÐ½Ð¸Ñ Ð¿Ð¾Ñле ÑÑÑановки его в ÑиÑÑ).
# * `?` â ÑоздаÑÑ Ð¿ÑедикаÑ.
# * `!` â ÑоздаÑÑ clearer.
#
::done_testing; }; subtest 'is => $permissions' => sub {
package ExIs { use Aion;
has rw => (is => 'rw?!');
has ro => (is => 'ro+');
has wo => (is => 'wo-?');
}
eval {ExIs->new}; local ($::_g0 = $@, $::_e0 = 'ro required!'); ok defined($::_g0) && $::_g0 =~ /^${\quotemeta $::_e0}/, 'ExIs->new # @-> ro required!' or ::diag ::_string_diff($::_g0, $::_e0, 1); undef $::_g0; undef $::_e0;
eval {ExIs->new(ro => 10, wo => -10)}; local ($::_g0 = $@, $::_e0 = 'wo excessive!'); ok defined($::_g0) && $::_g0 =~ /^${\quotemeta $::_e0}/, 'ExIs->new(ro => 10, wo => -10) # @-> wo excessive!' or ::diag ::_string_diff($::_g0, $::_e0, 1); undef $::...
local ($::_g0 = do {ExIs->new(ro => 10)->has_rw}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'ExIs->new(ro => 10)->has_rw # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {ExIs->new(ro => 10, rw => 20)->has_rw}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'ExIs->new(ro => 10, rw => 20)->has_rw # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $:...
local ($::_g0 = do {ExIs->new(ro => 10, rw => 20)->clear_rw->has_rw}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'ExIs->new(ro => 10, rw => 20)->clear_rw->has_rw # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); ...
local ($::_g0 = do {ExIs->new(ro => 10)->ro}, $::_e0 = do {10}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'ExIs->new(ro => 10)->ro # -> 10' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {ExIs->new(ro => 10)->wo(30)->has_wo}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'ExIs->new(ro => 10)->wo(30)->has_wo # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0...
eval {ExIs->new(ro => 10)->wo}; local ($::_g0 = $@, $::_e0 = 'Feature wo cannot be get!'); ok defined($::_g0) && $::_g0 =~ /^${\quotemeta $::_e0}/, 'ExIs->new(ro => 10)->wo # @-> Feature wo cannot be get!' or ::diag ::_string_diff($::_g0, $::_e0, 1);...
local ($::_g0 = do {ExIs->new(ro => 10)->rw(30)->rw}, $::_e0 = do {30}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'ExIs->new(ro => 10)->rw(30)->rw # -> 30' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
#
# ФÑнкÑÐ¸Ñ Ñ `*` не ÑдеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð·Ð½Ð°Ñение:
#
package Node { use Aion;
has parent => (is => "rw*", isa => Maybe[Object["Node"]]);
}
my $root = Node->new;
my $node = Node->new(parent => $root);
local ($::_g0 = do {$node->parent->parent}, $::_e0 = do {undef}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$node->parent->parent # -> undef' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
undef $root;
local ($::_g0 = do {$node->parent}, $::_e0 = do {undef}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$node->parent # -> undef' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
# And by setter:
$node->parent($root = Node->new);
local ($::_g0 = do {$node->parent->parent}, $::_e0 = do {undef}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$node->parent->parent # -> undef' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
undef $root;
local ($::_g0 = do {$node->parent}, $::_e0 = do {undef}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$node->parent # -> undef' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
#
# ## isa => $type
#
# УказÑÐ²Ð°ÐµÑ Ñип, а ÑоÑнее â валидаÑоÑ, ÑиÑи.
#
# ÐÐ¾Ð¶ÐµÑ Ð¿ÑинимаÑÑ:
#
# * `Aion::Type` â Aion ÑÑÐ°Ð·Ñ Ð¸Ð¼Ð¿Ð¾ÑÑиÑÑÐµÑ Ð² Ð¿Ð°ÐºÐµÑ Ð²Ñе ÑÐ¸Ð¿Ñ Ð¸Ð· [Aion::Types](https://metacpan.org/pod/Aion::Types).
# * СÑÑоки воÑпÑимаÑÑÑÑ ÐºÐ°Ðº пакеÑÑ Ð¸ обоÑаÑиваÑÑÑÑ Ð² `Object`.
# * ÐодпÑогÑÐ°Ð¼Ð¼Ñ â ÑеÑÑиÑÑемое знаÑение пеÑедаÑÑÑÑ Ð² `$_` и подпÑогÑамма возвÑаÑÐ°ÐµÑ Ð±Ñлево знаÑение.
# * ÐбÑекÑÑ Ñ Ð¿ÐµÑегÑÑженнÑм опеÑаÑоÑом `&{}`. ÐÑли Ñ Ñакого обÑекÑа еÑÑÑ ÐµÑÑ Ð¸ меÑод `coerce`, Ñо он бÑÐ´ÐµÑ ÑÑавÑÑвоваÑÑ Ð² пÑиведениÑÑ
, еÑли ÑказаÑ...
#
::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;
#
# ## coerce => (1|0)
#
# ÐклÑÑÐ°ÐµÑ Ð¿ÑеобÑÐ°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñипов.
#
::done_testing; }; subtest 'coerce => (1|0)' => sub {
package ExCoerce { use Aion;
has x => (is => 'ro', isa => Int, coerce => 1);
}
local ($::_g0 = do {ExCoerce->new(x => 10.4)->x}, $::_e0 = do {10}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'ExCoerce->new(x => 10.4)->x # -> 10' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {ExCoerce->new(x => 10.5)->x}, $::_e0 = do {11}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'ExCoerce->new(x => 10.5)->x # -> 11' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
#
# ## default => $value
#
# ÐнаÑение по ÑмолÑÐ°Ð½Ð¸Ñ ÑÑÑанавливаеÑÑÑ Ð² конÑÑÑÑкÑоÑе, еÑли паÑамеÑÑ Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ ÑиÑи оÑÑÑÑÑÑвÑеÑ.
#
::done_testing; }; subtest 'default => $value' => sub {
package ExDefault { use Aion;
has x => (is => 'ro', default => 10);
}
local ($::_g0 = do {ExDefault->new->x}, $::_e0 = do {10}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'ExDefault->new->x # -> 10' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {ExDefault->new(x => 20)->x}, $::_e0 = do {20}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'ExDefault->new(x => 20)->x # -> 20' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
#
# ÐÑли `$value` ÑвлÑеÑÑÑ Ð¿Ð¾Ð´Ð¿ÑогÑаммой, Ñо подпÑогÑамма ÑÑиÑаеÑÑÑ ÐºÐ¾Ð½ÑÑÑÑкÑоÑом знаÑÐµÐ½Ð¸Ñ ÑиÑи. ÐÑполÑзÑеÑÑÑ Ð»ÐµÐ½Ð¸Ð²Ð¾Ðµ вÑÑиÑление, еÑли Ð½ÐµÑ Ð°Ñ...
#
my $count = 10;
package ExLazy { use Aion;
has x => (default => sub {
my ($self) = @_;
++$count
});
}
my $ex = ExLazy->new;
local ($::_g0 = do {$count}, $::_e0 = do {10}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$count # -> 10' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {$ex->x}, $::_e0 = do {11}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$ex->x # -> 11' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {$count}, $::_e0 = do {11}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$count # -> 11' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {$ex->x}, $::_e0 = do {11}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$ex->x # -> 11' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {$count}, $::_e0 = do {11}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$count # -> 11' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
#
# ## lazy => (1|0)
#
# ÐÑÐ¿ÐµÐºÑ `lazy` вклÑÑÐ°ÐµÑ Ð¸Ð»Ð¸ оÑклÑÑÐ°ÐµÑ Ð»ÐµÐ½Ð¸Ð²Ð¾Ðµ вÑÑиÑление знаÑÐµÐ½Ð¸Ñ Ð¿Ð¾ ÑмолÑÐ°Ð½Ð¸Ñ (`default`).
#
# Ðо ÑмолÑÐ°Ð½Ð¸Ñ Ð¾Ð½ вклÑÑен ÑолÑко еÑли знаÑение по ÑмолÑÐ°Ð½Ð¸Ñ ÑвлÑеÑÑÑ Ð¿Ð¾Ð´Ð¿ÑогÑаммой.
#
::done_testing; }; subtest 'lazy => (1|0)' => sub {
package ExLazy0 { use Aion;
has x => (is => 'ro?', lazy => 0, default => sub { 5 });
}
my $ex0 = ExLazy0->new;
local ($::_g0 = do {$ex0->has_x}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$ex0->has_x # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {$ex0->x}, $::_e0 = do {5}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$ex0->x # -> 5' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
package ExLazy1 { use Aion;
has x => (is => 'ro?', lazy => 1, default => 6);
}
my $ex1 = ExLazy1->new;
local ($::_g0 = do {$ex1->has_x}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$ex1->has_x # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {$ex1->x}, $::_e0 = do {6}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$ex1->x # -> 6' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
#
# ## eon => (1|2|$key)
#
# С помоÑÑÑ Ð°ÑпекÑа `eon` ÑеализÑеÑÑÑ Ð¿Ð°ÑÑеÑн **Dependency Injection**.
#
# Ðн ÑвÑзÑÐ²Ð°ÐµÑ ÑвойÑÑво Ñ ÑеÑвиÑом из конÑейнеÑа `Aion->pleroma`.
#
# ÐнаÑением аÑпекÑа Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ ÐºÐ»ÑÑ ÑеÑвиÑа, 1 или 2.
#
# * ÐÑли 1 â Ñогда клÑÑÑм бÑÐ´ÐµÑ Ð¿Ð°ÐºÐµÑ Ð² `isa => Object['Packet']`.
# * ÐÑли 2 â Ñогда клÑÑÑм бÑÐ´ÐµÑ "пакеÑ#ÑвойÑÑво".
#
# Файл lib/CounterEon.pm:
#@> lib/CounterEon.pm
#>> package CounterEon;
#>> #@eon ex.counter
#>> use Aion;
#>>
#>> has accomulator => (isa => 'AccomulatorEon', eon => 1);
#>>
#>> 1;
#@< EOF
#
# Файл lib/AccomulatorEon.pm:
#@> lib/AccomulatorEon.pm
#>> package AccomulatorEon;
#>> #@eon
#>> use Aion;
#>>
#>> has power => (isa => 'PowerEon', eon => 2);
#>>
#>> 1;
#@< EOF
#
# Файл lib/PowerEon.pm:
#@> lib/PowerEon.pm
#>> package PowerEon;
#>> use Aion;
#>>
#>> has counter => (eon => 'ex.counter');
#>>
#>> #@eon
#>> sub power { shift->new }
#>>
#>> 1;
#@< EOF
#
# ÐÑполÑзÑем плеÑÐ¾Ð¼Ñ Ð»Ð¾ÐºÐ°Ð»Ñно:
#
::done_testing; }; subtest 'eon => (1|2|$key)' => sub {
{
use Aion::Pleroma;
my $pleroma = Aion::Pleroma->new(ini => undef, pleroma => {
'ex.counter' => 'CounterEon#new',
AccomulatorEon => 'AccomulatorEon#new',
'PowerEon#power' => 'PowerEon#power',
});
local *Aion::pleroma = sub { $pleroma };
my $counter = Aion->pleroma->get('ex.counter');
local ($::_g0 = do {$counter->accomulator->power->counter}, $::_e0 = do {$counter}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, ' $counter->accomulator->power->counter # -> $counter' or ::diag ::_struct_diff($::_g0, $::_e0); undef $...
}
local ($::_g0 = do {Aion->pleroma->get('ex.counter')}, $::_e0 = do {undef}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'Aion->pleroma->get(\'ex.counter\') # -> undef' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $:...
#
# См. [Aion::Pleroma](https://metacpan.org/pod/Aion::Pleroma).
#
# ## trigger => $sub
#
# `$sub` вÑзÑваеÑÑÑ Ð¿Ð¾Ñле ÑÑÑановки ÑвойÑÑва в конÑÑÑÑкÑоÑе (`new`) или ÑеÑез ÑеÑÑеÑ.
#
# ÐÑÐ¸Ð¼Ð¾Ð»Ð¾Ð³Ð¸Ñ `trigger` â впÑÑÑиÑÑ.
#
::done_testing; }; subtest 'trigger => $sub' => sub {
package ExTrigger { use Aion;
has x => (trigger => sub {
my ($self, $old_value) = @_;
$self->y($old_value + $self->x);
});
has y => ();
}
my $ex = ExTrigger->new(x => 10);
local ($::_g0 = do {$ex->y}, $::_e0 = do {10}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$ex->y # -> 10' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
$ex->x(20);
local ($::_g0 = do {$ex->y}, $::_e0 = do {30}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$ex->y # -> 30' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
#
# ## release => $sub
#
# `$sub` вÑзÑваеÑÑÑ Ð¿ÐµÑед возвÑаÑом ÑвойÑÑва из обÑекÑа ÑеÑез геÑÑеÑ.
#
# ÐÑÐ¸Ð¼Ð¾Ð»Ð¾Ð³Ð¸Ñ `release` â вÑпÑÑÑиÑÑ.
#
::done_testing; }; subtest 'release => $sub' => sub {
package ExRelease { use Aion;
has x => (release => sub {
my ($self, $value) = @_;
$_[1] = $value + 1;
});
}
my $ex = ExRelease->new(x => 10);
local ($::_g0 = do {$ex->x}, $::_e0 = do {11}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$ex->x # -> 11' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
#
# ## init_arg => $name
#
# ÐенÑÐµÑ Ð¸Ð¼Ñ ÑвойÑÑва в конÑÑÑÑкÑоÑе.
#
::done_testing; }; subtest 'init_arg => $name' => sub {
package ExInitArg { use Aion;
has x => (is => 'ro+', init_arg => 'init_x');
local ($::_g0 = do {ExInitArg->new(init_x => 10)->x}, $::_e0 = do {10}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, ' ExInitArg->new(init_x => 10)->x # -> 10' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
}
#
# ## accessor => $name
#
# ÐенÑÐµÑ Ð¸Ð¼Ñ Ð°ÐºÑеÑÑоÑа.
#
::done_testing; }; subtest 'accessor => $name' => sub {
package ExAccessor { use Aion;
has x => (is => 'rw', accessor => '_x');
local ($::_g0 = do {ExAccessor->new->_x(10)->_x}, $::_e0 = do {10}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, ' ExAccessor->new->_x(10)->_x # -> 10' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
}
#
# ## writer => $name
#
# СоздаÑÑ ÑеÑÑÐµÑ Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ `$name` Ð´Ð»Ñ ÑвойÑÑва.
#
::done_testing; }; subtest 'writer => $name' => sub {
package ExWriter { use Aion;
has x => (is => 'ro', writer => '_set_x');
local ($::_g0 = do {ExWriter->new->_set_x(10)->x}, $::_e0 = do {10}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, ' ExWriter->new->_set_x(10)->x # -> 10' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
}
#
# ## reader => $name
#
# СоздаÑÑ Ð³ÐµÑÑÐµÑ Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ `$name` Ð´Ð»Ñ ÑвойÑÑва.
#
::done_testing; }; subtest 'reader => $name' => sub {
package ExReader { use Aion;
has x => (is => 'wo', reader => '_get_x');
local ($::_g0 = do {ExReader->new(x => 10)->_get_x}, $::_e0 = do {10}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, ' ExReader->new(x => 10)->_get_x # -> 10' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
}
#
# ## predicate => $name
#
# СоздаÑÑ Ð¿ÑÐµÐ´Ð¸ÐºÐ°Ñ Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ `$name` Ð´Ð»Ñ ÑвойÑÑва. СоздаÑÑ Ð¿ÑÐµÐ´Ð¸ÐºÐ°Ñ Ñо ÑÑандаÑÑнÑм именем можно Ñак же ÑеÑез `is => '?'`.
#
::done_testing; }; subtest 'predicate => $name' => sub {
package ExPredicate { use Aion;
has x => (predicate => '_has_x');
my $ex = ExPredicate->new;
local ($::_g0 = do {$ex->_has_x}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, ' $ex->_has_x # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {$ex->x(10)->_has_x}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, ' $ex->x(10)->_has_x # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
}
#
# ## clearer => $name
#
# СоздаÑÑ Ð¾ÑиÑÑиÑÐµÐ»Ñ Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ `$name` Ð´Ð»Ñ ÑвойÑÑва. СоздаÑÑ Ð¾ÑиÑÑиÑÐµÐ»Ñ Ñо ÑÑандаÑÑнÑм именем можно Ñак же ÑеÑез `is => '!'`.
#
::done_testing; }; subtest 'clearer => $name' => sub {
package ExClearer { use Aion;
has x => (is => '?', clearer => 'clear_x_');
}
my $ex = ExClearer->new;
local ($::_g0 = do {$ex->has_x}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$ex->has_x # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
$ex->clear_x_;
local ($::_g0 = do {$ex->has_x}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$ex->has_x # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
$ex->x(10);
local ($::_g0 = do {$ex->has_x}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$ex->has_x # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
$ex->clear_x_;
local ($::_g0 = do {$ex->has_x}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$ex->has_x # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
#
# ## cleaner => $sub
#
# `$sub` вÑзÑваеÑÑÑ Ð¿Ñи вÑзове декÑÑÑÑкÑоÑа или `$object->clear_feature`, но ÑолÑко еÑли ÑвойÑÑво имееÑÑÑ (Ñм. `$object->has_feature`).
#
# ÐаннÑй аÑÐ¿ÐµÐºÑ Ð¿ÑинÑдиÑелÑно ÑоздаÑÑ Ð¿ÑÐµÐ´Ð¸ÐºÐ°Ñ Ð¸ clearer.
#
::done_testing; }; subtest 'cleaner => $sub' => sub {
package ExCleaner { use Aion;
our $x;
has x => (is => '!', cleaner => sub {
my ($self) = @_;
$x = $self->x
});
}
local ($::_g0 = do {$ExCleaner::x}, $::_e0 = do {undef}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$ExCleaner::x # -> undef' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
ExCleaner->new(x => 10);
local ($::_g0 = do {$ExCleaner::x}, $::_e0 = do {10}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$ExCleaner::x # -> 10' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
my $ex = ExCleaner->new(x => 12);
local ($::_g0 = do {$ExCleaner::x}, $::_e0 = do {10}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$ExCleaner::x # -> 10' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
$ex->clear_x;
local ($::_g0 = do {$ExCleaner::x}, $::_e0 = do {12}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$ExCleaner::x # -> 12' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
undef $ex;
local ($::_g0 = do {$ExCleaner::x}, $::_e0 = do {12}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$ExCleaner::x # -> 12' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
#
# # ATTRIBUTES
#
# `Aion` добавлÑÐµÑ Ð² Ð¿Ð°ÐºÐµÑ ÑнивеÑÑалÑнÑе аÑÑибÑÑÑ.
#
# ## :Isa (@signature)
#
# ÐÑÑибÑÑ `Isa` пÑовеÑÑÐµÑ ÑигнаÑÑÑÑ ÑÑнкÑии.
#
::done_testing; }; subtest ':Isa (@signature)' => sub {
package MaybeCat { use Aion;
sub is_cat : Isa(Me => Str => Bool) {
my ($self, $anim) = @_;
$anim =~ /(cat)/
}
}
my $anim = MaybeCat->new;
local ($::_g0 = do {$anim->is_cat('cat')}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$anim->is_cat(\'cat\') # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {$anim->is_cat('dog')}, $::_e0 = do {""}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, '$anim->is_cat(\'dog\') # -> ""' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
eval {MaybeCat->is_cat("cat")}; local ($::_g0 = $@, $::_e0 = 'Arguments of method `is_cat` must have the type Tuple[Me, Str].'); ok defined($::_g0) && $::_g0 =~ /^${\quotemeta $::_e0}/, 'MaybeCat->is_cat("cat") # @-> Arguments of method `is_cat` must...
eval {my @items = $anim->is_cat("cat")}; local ($::_g0 = $@, $::_e0 = 'Returns of method `is_cat` must have the type Tuple[Bool].'); ok defined($::_g0) && $::_g0 =~ /^${\quotemeta $::_e0}/, 'my @items = $anim->is_cat("cat") # @-> Returns of method `i...
#
# ÐÑÑибÑÑ Isa позволÑÐµÑ Ð¾Ð±ÑÑвиÑÑ ÑÑебÑемÑе ÑÑнкÑии:
#
package Anim { use Aion -role;
sub is_cat : Isa(Me => Bool);
}
package Cat { use Aion; with qw/Anim/;
sub is_cat : Isa(Me => Bool) { 1 }
}
package Dog { use Aion; with qw/Anim/;
sub is_cat : Isa(Me => Bool) { 0 }
}
package Mouse { use Aion; with qw/Anim/;
sub is_cat : Isa(Me => Int) { 0 }
}
local ($::_g0 = do {Cat->new->is_cat}, $::_e0 = do {1}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'Cat->new->is_cat # -> 1' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
local ($::_g0 = do {Dog->new->is_cat}, $::_e0 = do {0}); ::ok defined($::_g0) == defined($::_e0) && $::_g0 eq $::_e0, 'Dog->new->is_cat # -> 0' or ::diag ::_struct_diff($::_g0, $::_e0); undef $::_g0; undef $::_e0;
eval {Mouse->new}; local ($::_g0 = $@, $::_e0 = 'Signature mismatch: is_cat(Me => Bool) of Anim <=> is_cat(Me => Int) of Mouse'); ok defined($::_g0) && $::_g0 =~ /^${\quotemeta $::_e0}/, 'Mouse->new # @-> Signature mismatch: is_cat(Me => Bool) of Ani...
#
# # SEE ALSO
#
# ÐкоÑиÑÑема Aion:
#
# * [Aion::Annotation](https://metacpan.org/pod/Aion::Annotation)
# * [Aion::Carp](https://metacpan.org/pod/Aion::Carp)
# * [Aion::Enum](https://metacpan.org/pod/Aion::Enum)
# * [Aion::Format](https://metacpan.org/pod/Aion::Format)
# * [Aion::Fs](https://metacpan.org/pod/Aion::Fs)
# * [Aion::Query](https://metacpan.org/pod/Aion::Query)
# * [Aion::Run](https://metacpan.org/pod/Aion::Run)
# * [Aion::Spirit](https://metacpan.org/pod/Aion::Spirit)
# * [Aion::Surf](https://metacpan.org/pod/Aion::Surf)
# * [Aion::Telemetry](https://metacpan.org/pod/Aion::Telemetry)
# * [config](https://metacpan.org/release/DART/config-1.4.5/view/lib/config.pm)
# * [Liveman](https://metacpan.org/pod/Liveman)
#
# ÐодобнÑе ÐÐÐ-ÑÑеймвоÑки:
#
# * [Mouse](https://metacpan.org/pod/Mouse)
# * [Moose](https://metacpan.org/pod/Moose)
# * [Moo](https://metacpan.org/pod/Moo)
# * [Mo](https://metacpan.org/pod/Mo)
# * [M](https://metacpan.org/pod/M)
# * [Class::Accessor](https://metacpan.org/pod/Class::Accessor)
# * [Acme::Has::Tiny](https://metacpan.org/pod/Acme::Has::Tiny)
#
# Ðе Moose-подобнÑе:
#
# * [Object::Pad](https://metacpan.org/pod/Object::Pad)
#
# # AUTHOR
#
# Yaroslav O. Kosmina <dart@cpan.org>
#
# # LICENSE
#
# â **GPLv3**
#
# # COPYRIGHT
#
# The Aion module is copyright © 2023 Yaroslav O. Kosmina. Rusland. All rights reserved.
::done_testing;
};
::done_testing;
( run in 1.612 second using v1.01-cache-2.11-cpan-d80b1682f3f )