File Coverage

blib/lib/Bread/Board/Service/Deferred.pm
Criterion Covered Total %
statement 18 52 34.6
branch 6 20 30.0
condition 2 6 33.3
subroutine 7 16 43.7
pod 0 4 0.0
total 33 98 33.6


line stmt bran cond sub pod time code
1             package Bread::Board::Service::Deferred;
2             our $AUTHORITY = 'cpan:STEVAN';
3             # ABSTRACT: Helper for holding a service that is not quite constructed yet
4             $Bread::Board::Service::Deferred::VERSION = '0.35';
5 63     63   435 use Moose ();
  63         1199  
  63         22465  
6              
7             use overload
8             # cover your basic operatins ...
9 0     0   0 'bool' => sub { 1 },
10             '""' => sub {
11 0     0   0 $_[0] = $_[0]->{service}->get;
12 0 0       0 if (my $func = overload::Method($_[0], '""')) {
13 0         0 return $_[0]->$func();
14             }
15 0         0 return overload::StrVal($_[0]);
16             },
17             # cover your basic dereferncers
18             '%{}' => sub {
19 19 50   19   356 return $_[0] if (caller)[0] eq 'Bread::Board::Service::Deferred';
20 0         0 $_[0] = $_[0]->{service}->get;
21 0         0 $_[0]
22             },
23 0     0   0 '@{}' => sub { $_[0] = $_[0]->{service}->get; $_[0] },
  0         0  
24 0     0   0 '${}' => sub { $_[0] = $_[0]->{service}->get; $_[0] },
  0         0  
25 0     0   0 '&{}' => sub { $_[0] = $_[0]->{service}->get; $_[0] },
  0         0  
26 0     0   0 '*{}' => sub { $_[0] = $_[0]->{service}->get; $_[0] },
  0         0  
27             ## and as a last ditch resort ...
28             nomethod => sub {
29 2     2   1275 $_[0] = $_[0]->{service}->get;
30 2 50 33     12 return overload::StrVal($_[0]) if $_[3] eq '""' && !overload::Method($_[0], $_[3]);
31 2 50       14 if (my $func = overload::Method($_[0], $_[3])) {
32 0         0 return $_[0]->$func($_[1]);
33             }
34 2         156 return $_[0]; # if all else fails, just return the object
35             },
36 63     63   2629 ;
  63         141  
  63         2532  
37              
38             sub new {
39 5     5 0 20 my ($class, %params) = @_;
40 5 50 33     32 (Scalar::Util::blessed($params{service}) && $params{service}->does('Bread::Board::Service'))
41             || Carp::confess "You can only defer Bread::Board::Service instances";
42 5         1413 bless { service => $params{service} } => $class;
43             }
44              
45             sub meta {
46 0 0   0 0 0 if ($_[0]->{service}->can('class')) {
47 0         0 my $class = $_[0]->{service}->class;
48 0         0 return $class->meta;
49             }
50 0         0 $_[0] = $_[0]->{service}->get;
51 0         0 (shift)->meta;
52             }
53              
54             sub can {
55 0 0   0 0 0 if ($_[0]->{service}->can('class')) {
56 0         0 my $class = $_[0]->{service}->class;
57 0         0 return $class->can($_[1]);
58             }
59 0         0 $_[0] = $_[0]->{service}->get;
60 0         0 (shift)->can(shift);
61             }
62              
63             sub isa {
64 7 50   7 0 4541 if ($_[0]->{service}->can('class')) {
65 7         18 my $class = $_[0]->{service}->class;
66 7 50       34 return 1 if $class eq $_[1];
67 0         0 return $class->isa($_[1]);
68             }
69 0         0 $_[0] = $_[0]->{service}->get;
70 0         0 (shift)->isa(shift);
71             }
72              
73 3     3   1763 sub DESTROY { (shift)->{service} = undef }
74              
75             sub AUTOLOAD {
76 0     0     my ($subname) = our $AUTOLOAD =~ /([^:]+)$/;
77 0           $_[0] = $_[0]->{service}->get;
78 0           my $func = $_[0]->can($subname);
79 0 0         (ref($func) eq 'CODE')
80             || Carp::confess "You cannot call '$subname'";
81 0           goto &$func;
82             }
83              
84             1;
85              
86             __END__
87              
88             =pod
89              
90             =encoding UTF-8
91              
92             =head1 NAME
93              
94             Bread::Board::Service::Deferred - Helper for holding a service that is not quite constructed yet
95              
96             =head1 VERSION
97              
98             version 0.35
99              
100             =head1 DESCRIPTION
101              
102             Class for proxy objects used when L<resolving circular
103             dependencies|Bread::Board::Service::WithDependencies/resolve_dependencies>.
104              
105             This class uses a few nasty tricks: replacing C<$_[0]>, using
106             C<AUTOLOAD>, overriding C<isa> C<meta> and C<can>, heavy operator
107             overloading... you should probably not take inspiration from this code
108             unless you really know what you're doing.
109              
110             In practice, a variable containing an instance of
111             C<Bread::Board::Service::Deferred> will have its value changed to the
112             actual value instantiated by the service at the first opportunity, and
113             you should not notice that this class was ever there.
114              
115             =for Pod::Coverage can isa meta new
116              
117             =head1 AUTHOR
118              
119             Stevan Little <stevan@iinteractive.com>
120              
121             =head1 BUGS
122              
123             Please report any bugs or feature requests on the bugtracker website
124             https://github.com/stevan/BreadBoard/issues
125              
126             When submitting a bug or request, please include a test-file or a
127             patch to an existing test-file that illustrates the bug or desired
128             feature.
129              
130             =head1 COPYRIGHT AND LICENSE
131              
132             This software is copyright (c) 2017, 2016, 2015, 2014, 2013, 2011, 2009 by Infinity Interactive.
133              
134             This is free software; you can redistribute it and/or modify it under
135             the same terms as the Perl 5 programming language system itself.
136              
137             =cut