Aion
view release on metacpan or search on metacpan
lib/Aion/Pleroma.pm view on Meta::CPAN
package Aion::Pleroma;
# ÐонÑÐµÐ¹Ð½ÐµÑ Ð´Ð»Ñ Ñонов (ÑеÑвиÑов)
use common::sense;
use config {
INI => 'etc/annotation/eon.ann',
PLEROMA => {},
AUTOWARE => 1,
};
use Aion;
# Файл Ñ Ð°Ð½Ð½Ð¾ÑаÑиÑми
has ini => (is => 'ro', isa => Maybe[Str], default => INI);
# ÐонÑигÑÑаÑиÑ: клÑÑ => клаÑÑ#меÑод_клаÑÑа
has pleroma => (is => 'ro', isa => HashRef[Str], default => sub {
my ($self) = @_;
my %pleroma = (%{&PLEROMA}, 'Aion::Pleroma' => 'Aion::Pleroma#new');
return \%pleroma unless defined $self->ini and -e $self->ini;
open my $f, '<:utf8', INI or die "Not open ${\$self->ini}: $!";
while(<$f>) {
close($f), die "${\$self->ini} corrupt at line $.: $_" unless /^([\w:]+)#(\w*),\d+=(.*)$/;
my ($pkg, $sub, $key) = ($1, $2, $3);
my $action = join "#", $pkg, $sub || 'new';
$key = $key ne ""? $key: ($sub? "$pkg#$sub": $pkg);
close($f), die "The eon $key is $pleroma{$key}, but added other $action" if exists $pleroma{$key};
$pleroma{$key} = $action;
}
close $f;
\%pleroma
});
# СовокÑпноÑÑÑ Ð¿Ð¾ÑождÑннÑÑ
Ñонов-ÑеÑвиÑов
has eon => (is => 'ro', isa => HashRef[Object], lazy => 0, default => sub { +{'Aion::Pleroma' => shift} });
# ÐолÑÑиÑÑ Ñон из конÑейнеÑа
sub get {
my ($self, $key) = @_;
my $eon = $self->{eon}{$key};
return $eon if $eon;
my $config = $self->pleroma->{$key};
if($config) {
my ($pkg, $method) = $config =~ /#/? ($`, $'): ();
eval "require $pkg" or die unless $pkg->can('new') || $pkg->can('does');
$self->{eon}{$key} = $pkg->$method;
}
elsif(AUTOWARE and $key =~ /^([\w:]+)(#\w+)?$/ and eval "require $1") { $self->autoware($key)->get($key) }
else { undef }
}
# ÐолÑÑиÑÑ Ñон из конÑейнеÑа или иÑклÑÑение, еÑли его Ñам неÑ
sub resolve {
my ($self, $key) = @_;
$self->get($key) // die "$key is'nt eon!"
}
# ÐобавиÑÑ Ð² плеÑÐ¾Ð¼Ñ Ð¿Ð°ÐºÐµÑ
sub autoware {
my ($self, $action, $key) = @_;
my ($pkg, $sub) = $action =~ /#/? ($`, $'): ($action, 'new');
$action = "$pkg#$sub";
$key //= $action =~ /#new$/? $pkg: $action;
if(my $action_exists = $self->pleroma->{$key}) {
die "Added eon $key twice, with $action ne $action_exists" if $action_exists ne $action;
}
else {
$self->pleroma->{$key} = $action;
}
$self
}
1;
__END__
=encoding utf-8
=head1 NAME
Aion::Pleroma - container of aeons
=head1 SYNOPSIS
use Aion::Pleroma;
my $pleroma = Aion::Pleroma->new;
$pleroma->get('user') # -> undef
$pleroma->resolve('user') # @-> user is'nt eon!
=head1 DESCRIPTION
Implements the dependency container pattern.
An eon is created when requesting from a container via the C<get> or C<resolve> method, or via the C<eon> aspect as a lazy C<default>. Laziness can be canceled via the C<lazy> aspect.
The container can be obtained using C<< Aion-E<gt>pleroma >>.
The configuration for creating eons is obtained from the C<PLEROMA> config and the annotation file (created by the C<Aion::Annotation> package). The annotation file can be replaced via the C<INI> config.
=head1 CONFIG
Module settings that can be set in C<.config.pm>:
=over
=item * INI => 'etc/annotation/eon.ann' â annotation file.
=item * PLEROMA => {} â additional set of eons.
=item * AUTOWARE => 1 â load modules automatically, even if they are not specified in the configuration.
=back
=head1 FEATURES
=head2 ini
Annotation file.
Aion::Pleroma->new->ini # => etc/annotation/eon.ann
=head2 pleroma
Configuration: key => 'class#class_method'.
File lib/Ex/Eon/AnimalEon.pm:
package Ex::Eon::AnimalEon;
#@eon
use common::sense;
use Aion;
has role => (is => 'ro');
( run in 1.064 second using v1.01-cache-2.11-cpan-fe3c2283af0 )