File Coverage

blib/lib/Resource/Silo.pm
Criterion Covered Total %
statement 54 54 100.0
branch 6 6 100.0
condition 8 12 66.6
subroutine 13 13 100.0
pod 1 1 100.0
total 82 86 95.3


line stmt bran cond sub pod time code
1             package Resource::Silo;
2              
3 48     48   6267092 use 5.010;
  48         206  
4 48     48   316 use strict;
  48         243  
  48         1755  
5 48     48   366 use warnings;
  48         109  
  48         4153  
6              
7             our $VERSION = '0.16';
8              
9 48     48   341 use Carp;
  48         148  
  48         4408  
10 48     48   613 use Scalar::Util qw( set_prototype );
  48         130  
  48         3455  
11              
12 48     48   30003 use Resource::Silo::Metadata;
  48         186  
  48         2543  
13 48     48   31465 use Resource::Silo::Container;
  48         221  
  48         2588  
14              
15             # This is a dummy block to hint IDEs.
16             # see 'import' below for _real_ resource & silo implementation
17 48     48   25605 use parent 'Exporter';
  48         16299  
  48         376  
18             our @EXPORT = qw( resource silo );
19             #@returns Resource::Silo::Container
20             sub silo (); ## no critic 'prototypes'
21             sub resource (@); ## no critic 'prototypes'
22              
23             # We'll need a global metadata storage
24             # to allow extending container classes
25             our %metadata;
26              
27             sub import {
28 55     55   1690 my ($self, @param) = @_;
29 55         207 my $caller = caller;
30 55         661 my $target;
31 55         112 my $shortcut = "silo";
32              
33 55         301 while (@param) {
34 37         91 my $flag = shift @param;
35 37 100       151 if ($flag eq '-class') {
    100          
36 34         188 $target = $caller;
37             } elsif ($flag eq '-shortcut') {
38 2         5 $shortcut = shift @param;
39 2 100 33     38 croak "-shortcut must be an identifier"
      66        
40             unless $shortcut and !ref $shortcut and $shortcut =~ /^[a-z_][a-z_0-9]*$/i;
41             } else {
42             # TODO if there's more than 3 elsifs, use jump table instead
43 1         193 croak "Unexpected parameter to 'use $self': '$flag'";
44             };
45             };
46              
47 53   66     292 $target //= __PACKAGE__."::container::".$caller;
48              
49 53         444 my $spec = Resource::Silo::Metadata->new($target);
50 53         205 $metadata{$target} = $spec;
51              
52 53         118 my $instance;
53             my $silo = set_prototype {
54             # cannot instantiate target until the package is fully defined,
55             # thus go lazy
56 64   100 64   442520 $instance //= $target->new;
57 53         771 } '';
58              
59 48     48   22509 no strict 'refs'; ## no critic
  48         149  
  48         3119  
60 48     48   365 no warnings 'redefine', 'once'; ## no critic
  48         100  
  48         11797  
61              
62 53         330 push @{"${target}::ISA"}, 'Resource::Silo::Container';
  53         999  
63              
64 53         307 *{"${caller}::resource"} = $spec->_make_dsl;
  53         321  
65 53         113 *{"${caller}::$shortcut"} = $silo;
  53         107634  
66             };
67              
68             sub get_meta {
69 1     1 1 4519 my ($self, $target) = @_;
70              
71 1         6 return $metadata{$target};
72             }
73              
74             1; # End of Resource::Silo
75              
76             __END__