Minions is yet another OOP automation module, roughly similar to Moo, but which has the addtional goal of putting Encapsulation centre stage. I wrote it because after reading How Large Does Your Project Have To Be to Justify Using Moose? (especially the comments by tye and JavaFan), I became increasingly disillusioned with the Moo(se) way of OOP (essentially OOP with no Encapsulation).
Here is a sample that implements the fixed size queue from
Re^5: The future of Perl? (that sub-thread also illustrates limitations of the Moo way of OOP)
package FixedSizeQueue;
use Minions
interface => [qw( push pop size )],
construct_with => {
max_items => {
assert => { positive_int => sub { $_[0] =~ /^\d+$/ && $_[0
+] > 0 } },
},
},
implementation => 'FixedSizeQueue::Default',
;
1;
package FixedSizeQueue::Default;
use Minions::Implementation
has => {
q => { default => sub { [ ] } },
max_size => {
init_arg => 'max_items',
},
},
;
sub size {
my ($self) = @_;
scalar @{ $self->{$__q} };
}
sub push {
my ($self, $val) = @_;
log_info($self);
push @{ $self->{$__q} }, $val;
if ($self->size > $self->{$__max_size}) {
$self->pop;
}
}
sub pop {
my ($self) = @_;
log_info($self);
shift @{ $self->{$__q} };
}
sub log_info {
my ($self) = @_;
warn sprintf "[%s] I have %d element(s)\n", scalar(localtime), $se
+lf->size;
}
1;
And a sample of usage:
% reply -I lib
0> use FixedSizeQueue
1> my $q = FixedSizeQueue->new(max_items => 3)
$res[0] = bless( {
'932db126-' => 'FixedSizeQueue::__Private',
'932db126-max_size' => 3,
'932db126-q' => []
}, 'FixedSizeQueue::__Minions' )
2> $q->can
$res[1] = [
'pop',
'push',
'size'
]
3> $q->push($_) for 1 .. 3
[Mon Jan 26 12:01:53 2015] I have 0 element(s)
[Mon Jan 26 12:01:53 2015] I have 1 element(s)
[Mon Jan 26 12:01:53 2015] I have 2 element(s)
$res[2] = ''
4> $q->pop
[Mon Jan 26 12:02:09 2015] I have 3 element(s)
$res[3] = 1
5> $q
$res[4] = bless( {
'932db126-' => 'FixedSizeQueue::__Private',
'932db126-max_size' => 3,
'932db126-q' => [
2,
3
]
}, 'FixedSizeQueue::__Minions' )
6> $q->push($_) for 4 .. 6
[Mon Jan 26 12:02:55 2015] I have 2 element(s)
[Mon Jan 26 12:02:55 2015] I have 3 element(s)
[Mon Jan 26 12:02:55 2015] I have 4 element(s)
[Mon Jan 26 12:02:55 2015] I have 3 element(s)
[Mon Jan 26 12:02:55 2015] I have 4 element(s)
$res[5] = ''
7> $q
$res[6] = bless( {
'932db126-' => 'FixedSizeQueue::__Private',
'932db126-max_size' => 3,
'932db126-q' => [
4,
5,
6
]
}, 'FixedSizeQueue::__Minions' )
8> $q->log_info()
Can't locate object method "log_info" via package "FixedSizeQueue::__M
+inions" at reply input line 1.
9>
Not all Moo features are supported (for this early release I've focused on those I actually use). Important differences from Moo include
- Attributes can be safely accessed inside classes without the overhead of a function call
- As a consequence of 1., attributes need not be exposed via methods (unless there is a good reason to do so).
- No need to clean up animal droppings
- Private subroutines via the mechanism shown in Re: OO - best way to have protected methods (packages)
- Class methods are "class only", and object methods are "object only"
- No compatibility with Moose
Feedback is much appreciated.