NAME
Evo::Comp
VERSION
version 0.0187
DESCRIPTION
Component-oriented programming
A new promising component-oriented programming concepts. Documentation will be available if someone will be willing to help write it.
Why not OO and Moose like?
The most problems with Moose like modules is with initialization. Let's take a look:
package My::Moose;
use Moose;
has foo => is =>'rw';
package main;
my $obj = My::Moose->new(fo => 3);
print $obj->foo;
As you can see, we passed fo
instead of foo
, and Moose silently ignored it. You should write a huge amout of extra tests to pervent such errors.
Also traditional OO programming suffers the fragile base class problems (use Google). To solve it, component oriented Evo::Comp
introduces flexible component roles Evo::Comp::Role.
So I decided to write all the stuff and name it component oriented programming. More explanation will be written later
SYNOPSYS
package main;
use Evo;
{
package My::Human;
use Evo '-Comp *';
has 'name' => 'unnamed';
has 'gender', is => 'ro', required => 1;
has age => check => sub($v) { $v >= 18 };
}
my $alex = My::Human::new(gender => 'male');
# default value "unnamed"
say $alex->name;
# fluent design
$alex->name('Alex')->age(18);
say $alex->name, ': ', $alex->age;
# will die, gender is required
My::Human::new();
# will die, age must be >= 18
My::Human::new(age => 17, gender => 'male');
My::Human::new()->age(17, gender => 'male');
Usage
creating component
Describe a component, use need to import "*" to get it worked
package My::Comp;
use Evo '-Comp *';
has 'simple';
You don't need to call something like __PACKAGE__->meta->make_immutable
unlike in Moose, components are fast enough by design.
new
important!!! Because Components reuse code horizontal, there's no need to pass the class string to every invocation of new
(or Evo::Comp::Out/"init"
). So instead of My::Class->new
use My::Comp::new
my $foo = My::Comp::new(simple => 1);
my $foo2 = My::Comp::new();
We're protected from common mistakes, because constructor won't accept unknown attributes
my $foo = My::Comp::new(SiMple => 1);
Storage
The big advantage of component that it's not tied with implementation. The default uses hashes Evo::Comp::Hash, but you can easily switch for example to Evo::Comp::Out and use any other refs
Declaring attribute
package My::Foo;
use Evo '-Comp *';
has 'simple';
has 'short' => 'value';
has 'foo' => default => 'value', is => 'rw', check => sub {1};
Syntax
Simple rw attribute
has 'simple';
# has 'simple', is => 'rw';
Attribute with default value: short form
has 'short' => 'value';
# has 'short', default => 'value';
Full form
has 'foo' => default => 'value', is => 'rw', check => sub {1};
Options
is
Can be 'rw' or 'ro'; Unlike Perl6 is 'rw' by default
default
Attribute will be filled with this value if isn't provided to the new
constructor You can't use references, but you can provide a coderef instead of value, in this case return value of an invocation of this function will be used.
has ref => sub { {} };
has ref => sub { {} };
lazy
Like default, but won't be filled at the first invocation, not in constructor.
required
Attributes with this options are required
check
You can provide function that will check passed value (via constuctor and changing), and if that function doesn't return true, an exception will be thrown.
has big => check => sub { shift > 10 };
You can also return (0, "CustomError")
to provide more expressive explanation
package main;
use Evo;
{
package My::Foo;
use Evo '-Comp *';
has big => check => sub($val) { $val > 10 ? 1 : (0, "not > 10"); };
};
my $foo = My::Foo::new(big => 11);
$foo->big(9); # will die
my $bar = My::Foo::new(big => 9); # will die
Code reuse
Instead of OO inheritance, wich suffers from fragile base class problem, Evo::Comp
provides Evo::Comp::Role. This is a perfect choice for code reuse because of it's safety and flexibility. Look at Evo::Comp::Role for more information
with
Load role and install all methods and attributes to the component. Supports "shortcuts" in Evo
package Person;
use Evo '-Comp *';
with ':LoudHuman', ':Human';
Circular requirements can be solved by requiring roles in the single with
. See "requires" in Evo::Comp::Role
AUTHOR
alexbyk.com
COPYRIGHT AND LICENSE
This software is copyright (c) 2016 by alexbyk.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.