Aion

 view release on metacpan or  search on metacpan

lib/Aion.pm  view on Meta::CPAN


=head1 NAME

Aion - a postmodern object system for Perl 5, such as “Mouse”, “Moose”, “Moo”, “Mo” and “M”, but with improvements

=head1 VERSION

2.2

=head1 SYNOPSIS

	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}";
		}
	
	}
	
	Calc->new(a => 1.1, b => 2)->result   # => 3.1

=head1 DESCRIPTION

Aion is OOP-framework for creating classes with B<features>, has B<aspects>, B<roles> and so on.

The properties declared through HAS are called B<features>.

And C<is>,C<isa>, C<default>, and so on inC<has> are called B<aspects>.

In addition to standard aspects, roles can add their own aspects using the B<aspect> subprogram.

The signature of the methods can be checked using the attribute C<:Isa(...)>.

=head1 SUBROUTINES IN CLASSES AND ROLES

C<Use Aion> imports types from the moduleC<Aion::Types> and the following subprograms:

=head2 has ($name, %aspects)

Creates a method for obtaining/setting the function (properties) of the class.

lib/Animal.pm file:

	package Animal;
	use Aion;
	
	has type => (is => 'ro+', isa => Str);
	has name => (is => 'rw-', isa => Str, default => 'murka');
	
	1;



	use lib "lib";
	use Animal;
	
	my $cat = Animal->new(type => 'cat');
	
	$cat->type   # => cat
	$cat->name   # => murka
	
	$cat->name("murzik");
	$cat->name   # => murzik

=head2 with

Adds to the module of the role. For each role, the C<import_with> method is called.

File lib/Role/Keys/Stringify.pm:

	package Role::Keys::Stringify;
	
	use Aion -role;
	
	sub keysify {
		my ($self) = @_;
		join ", ", sort keys %$self;
	}
	
	1;

File lib/Role/Values/Stringify.pm:

	package Role::Values::Stringify;
	
	use Aion -role;
	
	sub valsify {
		my ($self) = @_;
		join ", ", map $self->{$_}, sort keys %$self;
	}
	
	1;

File 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;



	use lib "lib";
	use Class::All::Stringify;
	
	my $s = Class::All::Stringify->new(key1=>"a", key2=>"b");
	
	$s->keysify	 # => key1, key2
	$s->valsify	 # => a, b

=head2 exactly ($package)

Checks that C<$package> is a super class for a given or this class itself.

Aion does not change the implementation of the C<isa> method and it finds both superclasses and roles (since both are added to the C<@ISA> package).

	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/ }
	
	Ex::C->exactly("Ex::A") # -> 1
	Ex::C->exactly("Ex::B") # -> 1
	Ex::C->exactly("Ex::X") # -> 1
	Ex::C->exactly("Ex::X1") # -> ""
	Ex::A->exactly("Ex::X") # -> 1
	Ex::A->exactly("Ex::A") # -> 1
	Ex::X->exactly("Ex::X") # -> 1

=head2 does ($package)

Checks that C<$package> is a role that is used in a class or another role.

	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/; }
	
	Ex::Z->does("Role::A") # -> 1
	Ex::Z->does("Role::B") # -> 1
	Ex::Z->does("Role::X") # -> 1
	Role::A->does("Role::X") # -> 1
	Role::A->does("Role::X1") # -> ""
	Ex::Z->does("Ex::Z") # -> ""

=head2 aspect ($aspect => sub { ... })

Adds the aspect to C<has> in the current class and its classroom classes or the current role and applies its classes.

	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);
	}
	



( run in 0.764 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )