File Coverage

blib/lib/Populous.pm
Criterion Covered Total %
statement 65 69 94.2
branch 6 8 75.0
condition n/a
subroutine 14 14 100.0
pod 0 3 0.0
total 85 94 90.4


line stmt bran cond sub pod time code
1             package Populous;
2             BEGIN {
3 1     1   935 $Populous::AUTHORITY = 'cpan:GETTY';
4             }
5             {
6             $Populous::VERSION = '0.001';
7             }
8             # ABSTRACT: Populate anything like a god
9              
10 1     1   2754 use Moo;
  1         29733  
  1         7  
11 1     1   4010 use Package::Stash;
  1         22949  
  1         4165  
12              
13             has classes => (
14             is => 'ro',
15             required => 1,
16             );
17              
18 1     1   1777 has cache => (
19             is => 'ro',
20             lazy => 1,
21             builder => sub {{}},
22             );
23              
24             has package_namespace => (
25             is => 'ro',
26             lazy => 1,
27             builder => sub {
28 1     1   995 my ( $self ) = @_;
29 1         4 my $class_id = "$self";
30 1         8 $class_id =~ s/[^\w\d]//g;
31 1         9 return "__POPULOUS_GENERATED_$class_id";
32             },
33             );
34              
35             sub class_to_package {
36 1     1 0 3 my ( $self, $class ) = @_;
37 1         5 return join("::",$self->package_namespace,$class);
38             }
39              
40             sub BUILD {
41 1     1 0 14589 my ( $self ) = @_;
42 1         4 my @classes = @{$self->classes};
  1         7  
43 1         27 my $stash = Package::Stash->new(ref $self);
44 1         7 while (@classes) {
45 1         3 my $class = shift @classes;
46 1         3 my $constructor = shift @classes;
47 1         5 my %functions;
48 1 50       6 if (ref $classes[0] eq 'HASH') {
49 1         2 my $functions_ref = shift @classes;
50 1         4 %functions = %{$functions_ref};
  1         7  
51             }
52 1         6 my $package = $self->class_to_package($class);
53             $stash->add_symbol('&new_'.$class,sub {
54 1     1   12 shift;
55 1         3 my $i = 0;
56 1         8 while (@_) {
57 3         10 my $id = shift;
58 3         5 my $arg = shift;
59 3         9 my $object = $constructor->($id,$arg);
60 3         71 $self->cache->{$class}->{$id} = bless [ $object, $id ], $package;
61 3         22 $i++;
62             }
63 1         4 return $i;
64 1         32 });
65             $stash->add_symbol('&delete_'.$class,sub {
66 1     1   653 shift;
67 1         3 my @killed;
68 1         3 for (@_) {
69 1         28 push @killed, (delete $self->cache->{$class}->{$_});
70             }
71 1         12 return @killed;
72 1         14 });
73             $stash->add_symbol('&get_'.$class,sub {
74 4     4   1852 shift;
75 4 50       12 if (wantarray) {
76 0         0 my @return;
77 0         0 for (@_) {
78 0         0 push @return, $self->cache->{$class}->{$_}->[0];
79             }
80 0         0 return @return;
81             } else {
82 4         108 return $self->cache->{$class}->{$_[0]}->[0];
83             }
84 1         13 });
85             $stash->add_symbol('&'.$class,sub {
86 7     7   4549 shift;
87 7         16 my ( $id, $func, @args ) = @_;
88 7 100       305 return unless defined $self->cache->{$class}->{$id};
89 6         170 my $object = $self->cache->{$class}->{$id};
90 6 100       58 return $object unless defined $func;
91 2         8 return $object->$func(@args);
92 1         16 });
93             $functions{delete} = sub {
94 1     1   23 delete $self->cache->{$class}->{$_->[1]};
95 1         6 };
96 1         7 $self->create_package($package, %functions);
97             }
98             }
99              
100             sub create_package {
101 1     1 0 5 my ( $self, $package, %functions ) = @_;
102 1         10 my $stash = Package::Stash->new($package);
103 1         5 for my $function_name (keys %functions) {
104             $stash->add_symbol('&'.$function_name,sub {
105 7     7   12 my $self_ref = shift;
106 7         11 my $self = $self_ref->[0];
107 7         13 for ($self_ref) {
108 7         21 return $functions{$function_name}->($self,@_);
109             }
110 3         105 });
111             }
112             }
113              
114             1;
115              
116             __END__