File Coverage

lib/Context/Singleton.pm
Criterion Covered Total %
statement 49 50 98.0
branch 4 4 100.0
condition 6 7 85.7
subroutine 19 20 95.0
pod n/a
total 78 81 96.3


line stmt bran cond sub pod time code
1              
2 2     2   193380 use strict;
  2         13  
  2         99  
3 2     2   13 use warnings;
  2         4  
  2         71  
4 2     2   13 use feature 'state';
  2         5  
  2         306  
5              
6             package Context::Singleton;
7              
8             our $VERSION = v1.0.4;
9              
10 2     2   14 use parent 'Exporter::Tiny';
  2         4  
  2         12  
11              
12 2     2   4632 use Sub::Install qw();
  2         1786  
  2         38  
13 2     2   1098 use Variable::Magic qw();
  2         2322  
  2         49  
14              
15 2     2   847 use Context::Singleton::Frame;
  2         8  
  2         1131  
16              
17             our @EXPORT = keys %{ _by_frame_class_accessors () };
18              
19             sub _by_frame_class_accessors {
20 80     80   162 my ($frame_class) = @_;
21 80   100     309 $frame_class //= 'Context::Singleton::Frame';
22              
23 80         111 state %cache;
24              
25 80   66     287 return $cache{$frame_class} //= do {
26 3         17 my $current_frame = $frame_class->new;
27              
28             my $restore_context_wizard = Variable::Magic::wizard
29 4     4   5338 free => sub { $current_frame = $current_frame->parent; 1 },
  4         46  
30 3         17 ;
31              
32             my $frame = sub (&) {
33 4     4   21474 Variable::Magic::cast my $guard => $restore_context_wizard;
34 4         18 $current_frame = $current_frame->new;
35              
36 4         14 $_[0]->();
37 3         124 };
38              
39             +{
40 5     5   664 contrive => sub { $current_frame->contrive (@_) },
41 7     7   18747 current_frame => sub { $current_frame },
42 5     5   4657 deduce => sub { $current_frame->deduce (@_) },
43             frame => $frame,
44 3     3   774 is_deduced => sub { $current_frame->is_deduced (@_) },
45 6     6   638 load_rules => sub { $current_frame->load_rules (@_) },
46 5     5   25 proclaim => sub { $current_frame->proclaim (@_) },
47 0     0   0 trigger => sub { $current_frame->trigger (@_) },
48 3     3   12858 try_deduce => sub { $current_frame->try_deduce (@_) },
49 3         102 };
50             };
51             }
52              
53             sub _exporter_expand_sub {
54 73     73   4436 my ($class, $name, $args, $globals) = @_;
55              
56 73         182 return $name => _by_frame_class_accessors ($globals->{frame_class})->{$name};
57             }
58              
59             sub import {
60 9     9   10885 my ($class, @params) = @_;
61              
62 9 100       35 my $globals = Ref::Util::is_hashref ($params[0])
63             ? shift @params
64             : {}
65             ;
66              
67 9   100     44 $globals->{into} //= scalar caller;
68              
69 9         65 $class->SUPER::import ($globals, @params);
70              
71 5         19 _by_frame_class_accessors ($globals->{frame_class})->{load_rules}->(@{ $globals->{load_path} })
72 9 100       2502 if $globals->{load_path};
73              
74             }
75              
76             1;
77              
78             __END__