File Coverage

blib/lib/Resource/Silo.pm
Criterion Covered Total %
statement 57 57 100.0
branch 10 10 100.0
condition 10 13 76.9
subroutine 14 14 100.0
pod 1 1 100.0
total 92 95 96.8


line stmt bran cond sub pod time code
1             package Resource::Silo;
2              
3 49     49   4839203 use 5.010;
  49         179  
4 49     49   225 use strict;
  49         225  
  49         1240  
5 49     49   229 use warnings;
  49         90  
  49         3188  
6              
7             our $VERSION = '0.1702';
8              
9 49     49   235 use Carp;
  49         120  
  49         3333  
10 49     49   298 use Scalar::Util qw( set_prototype );
  49         70  
  49         2352  
11              
12 49     49   21131 use Resource::Silo::Metadata;
  49         152  
  49         1926  
13 49     49   24701 use Resource::Silo::Container;
  49         193  
  49         2154  
14              
15             # This is a dummy block to hint IDEs.
16             # see 'import' below for _real_ resource & silo implementation
17 49     49   20082 use parent 'Exporter';
  49         12144  
  49         238  
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 58     58   3506 my ($self, @param) = @_;
29 58         156 my $caller = caller;
30 58         604 my $target;
31             my $shortcut;
32              
33 58         205 while (@param) {
34 41         78 my $flag = shift @param;
35 41 100       128 if ($flag eq '-class') {
    100          
36 37         102 $target = $caller;
37             } elsif ($flag eq '-shortcut') {
38 3         8 $shortcut = shift @param;
39 3 100 33     70 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         164 croak "Unexpected parameter to 'use $self': '$flag'";
44             };
45             };
46              
47 56 100       142 if (!defined $target) {
48             # we're not in class mode, create a one-off package
49 19         33 $target = __PACKAGE__ . "::container::" . $caller;
50 19   100     102 $shortcut //= 'silo';
51             }
52              
53 56         352 my $spec = Resource::Silo::Metadata->new($target);
54 56         123 $metadata{$target} = $spec;
55              
56 56         89 my $instance;
57             my $shortcut_sub = defined $shortcut
58             ? set_prototype {
59             # cannot instantiate target until the package is fully defined,
60             # thus go lazy
61 64   100 64   410638 $instance //= $target->new;
62             } ''
63             : set_prototype {
64             # TODO 2027-01-01: remove the deprecation & just skip it entirely
65 1     1   20 croak "Resource::Silo: 'silo' is not exported anymore when -class is in action, use explicit -shortcut => ... instead"
66 56 100       632 } '';
67              
68 56   100     316 $shortcut //= 'silo'; # only for deprecation
69              
70 49     49   16906 no strict 'refs'; ## no critic
  49         85  
  49         1980  
71 49     49   210 no warnings 'redefine', 'once'; ## no critic
  49         77  
  49         9027  
72              
73 56         217 push @{"${target}::ISA"}, 'Resource::Silo::Container';
  56         769  
74              
75 56         230 *{"${caller}::resource"} = $spec->_make_dsl;
  56         277  
76 56         113 *{"${caller}::$shortcut"} = $shortcut_sub;
  56         77713  
77             };
78              
79             sub get_meta {
80 1     1 1 1882 my ($self, $target) = @_;
81              
82 1         5 return $metadata{$target};
83             }
84              
85             1; # End of Resource::Silo
86              
87             __END__