File Coverage

blib/lib/Bolts/Meta/Locator.pm
Criterion Covered Total %
statement 95 95 100.0
branch 5 6 83.3
condition n/a
subroutine 24 24 100.0
pod 1 1 100.0
total 125 126 99.2


line stmt bran cond sub pod time code
1             package Bolts::Meta::Locator;
2             $Bolts::Meta::Locator::VERSION = '0.142930';
3             # ABSTRACT: Standard meta locator for Bolts
4              
5 8     8   36 use Moose;
  8         12  
  8         42  
6              
7             with qw( Bolts::Role::RootLocator );
8              
9 8     8   39378 use Bolts::Artifact;
  8         2275  
  8         319  
10 8     8   4262 use Bolts::Artifact::Thunk;
  8         2034  
  8         270  
11 8     8   3635 use Bolts::Bag;
  8         1923  
  8         244  
12              
13 8     8   69 use Bolts::Blueprint::Built;
  8         12  
  8         160  
14 8     8   3174 use Bolts::Blueprint::Factory;
  8         2176  
  8         321  
15 8     8   48 use Bolts::Blueprint::Given;
  8         10  
  8         143  
16 8     8   30 use Bolts::Blueprint::Literal;
  8         8  
  8         135  
17              
18 8     8   3818 use Bolts::Injector::Parameter::ByName;
  8         2140  
  8         310  
19              
20 8     8   3873 use Bolts::Scope::Prototype;
  8         1991  
  8         292  
21 8     8   3281 use Bolts::Scope::Singleton;
  8         2121  
  8         252  
22              
23 8     8   47 use Class::Load;
  8         9  
  8         7763  
24              
25              
26 287     287 1 483 sub root { $_[0] }
27              
28              
29             has blueprint => (
30             is => 'ro',
31             isa => 'Object',
32             lazy_build => 1,
33             );
34              
35             sub _build_blueprint {
36 16     16   34 my $self = shift;
37              
38 16         153 my $bp = Bolts::Bag->start_bag(
39             package => 'Bolts::Meta::Locator::Blueprint',
40             such_that_each => {
41             does => 'Bolts::Blueprint',
42             },
43             );
44              
45 16 100       134 return $bp->name->new if $bp->is_finished_bag;
46              
47             $bp->add_artifact(
48             acquired => Bolts::Artifact::Thunk->new(
49             thunk => sub {
50 19     19   55 my ($self, $bag, %o) = @_;
51 19         68 Class::Load::load_class('Bolts::Blueprint::Acquired');
52 19         2744 Bolts::Blueprint::Acquired->new(%o);
53             },
54 8         359 ),
55             );
56              
57             $bp->add_artifact(
58             given => Bolts::Artifact::Thunk->new(
59             thunk => sub {
60 56     56   118 my ($self, $bag, %o) = @_;
61 56         147 Class::Load::load_class('Bolts::Blueprint::Given');
62 56         2883 Bolts::Blueprint::Given->new(%o);
63             },
64 8         645 ),
65             );
66              
67             $bp->add_artifact(
68             literal => Bolts::Artifact::Thunk->new(
69             thunk => sub {
70 21     21   49 my ($self, $bag, %o) = @_;
71 21         62 Class::Load::load_class('Bolts::Blueprint::Literal');
72 21         1096 Bolts::Blueprint::Literal->new(%o);
73             },
74 8         543 ),
75             );
76              
77             $bp->add_artifact(
78             built => Bolts::Artifact::Thunk->new(
79             thunk => sub {
80 18     18   48 my ($self, $bag, %o) = @_;
81 18         53 Class::Load::load_class('Bolts::Blueprint::Built');
82 18         1001 Bolts::Blueprint::Built->new(%o);
83             },
84 8         532 ),
85             );
86              
87             $bp->add_artifact(
88             built_injector => Bolts::Artifact::Thunk->new(
89             thunk => sub {
90 2     2   6 my ($self, $bag, %o) = @_;
91 2         8 Class::Load::load_class('Bolts::Blueprint::BuiltInjector');
92 2         634 Bolts::Blueprint::BuiltInjector->new(%o);
93             },
94 8         574 ),
95             );
96              
97             $bp->add_artifact(
98             factory => Bolts::Artifact::Thunk->new(
99             thunk => sub {
100 11     11   28 my ($self, $bag, %o) = @_;
101 11         38 Class::Load::load_class('Bolts::Blueprint::Factory');
102 11         623 Bolts::Blueprint::Factory->new(%o);
103             },
104 8         574 ),
105             );
106              
107             $bp->add_artifact(
108             parent_bag => Bolts::Artifact::Thunk->new(
109             thunk => sub {
110 1     1   3 my ($self, $bag, %o) = @_;
111 1         10 Class::Load::load_class('Bolts::Blueprint::ParentBag');
112 1         306 Bolts::Blueprint::ParentBag->new(%o);
113             },
114 8         609 ),
115             );
116              
117 8         361 $bp->finish_bag;
118              
119 8         350 return $bp->name->new;
120             }
121              
122              
123             has inference => (
124             is => 'ro',
125             isa => 'ArrayRef',
126             lazy_build => 1,
127             );
128              
129             sub _build_inference {
130 6     6   9 my $self = shift;
131              
132 6         177 my $singleton = $self->scope->singleton->get($self->scope);
133              
134             return [
135 6         214 Bolts::Artifact->new(
136             name => 'moose',
137             blueprint => Bolts::Blueprint::Factory->new(
138             class => 'Bolts::Inference::Moose',
139             ),
140             scope => $singleton,
141             ),
142             ];
143             }
144              
145              
146             has injector => (
147             is => 'ro',
148             isa => 'Object',
149             lazy_build => 1,
150             );
151              
152             sub _build_injector {
153 12     12   18 my $self = shift;
154              
155 12         327 my $prototype = $self->scope->prototype->get($self->scope);
156              
157 12         445 my $parameter_name = Bolts::Artifact->new(
158             name => 'parameter_name',
159             blueprint => Bolts::Blueprint::Factory->new(
160             class => 'Bolts::Injector::Parameter::ByName',
161             ),
162             scope => $prototype,
163             injectors => [
164             Bolts::Injector::Parameter::ByName->new(
165             key => 'key',
166             blueprint => Bolts::Blueprint::Given->new(
167             required => 1,
168             ),
169             ),
170             Bolts::Injector::Parameter::ByName->new(
171             key => 'blueprint',
172             blueprint => Bolts::Blueprint::Given->new(
173             required => 1,
174             ),
175             ),
176             Bolts::Injector::Parameter::ByName->new(
177             key => 'does',
178             blueprint => Bolts::Blueprint::Given->new(
179             required => 0,
180             ),
181             ),
182             Bolts::Injector::Parameter::ByName->new(
183             key => 'isa',
184             blueprint => Bolts::Blueprint::Given->new(
185             required => 0,
186             ),
187             ),
188             Bolts::Injector::Parameter::ByName->new(
189             key => 'name',
190             blueprint => Bolts::Blueprint::Given->new(
191             required => 0,
192             ),
193             ),
194             ],
195             );
196              
197 12         76 my $bag = Bolts::Bag->start_bag(
198             package => 'Bolts::Meta::Locator::Injector',
199             such_that_each => {
200             does => 'Bolts::Injector',
201             },
202             );
203              
204 12 100       50 return $bag->name->new if $bag->is_finished_bag;
205              
206 6         43 $bag->add_artifact( parameter_name => $parameter_name );
207            
208 6         464 $bag->add_artifact(
209             parameter_position => Bolts::Artifact->new(
210             name => 'parameter_position',
211             blueprint => Bolts::Blueprint::Factory->new(
212             class => 'Bolts::Injector::Parameter::ByPosition',
213             ),
214             infer => 'options',
215             scope => $prototype,
216             ),
217             );
218              
219 6         457 $bag->add_artifact(
220             setter => Bolts::Artifact->new(
221             name => 'setter',
222             blueprint => Bolts::Blueprint::Factory->new(
223             class => 'Bolts::Injector::Setter',
224             ),
225             infer => 'options',
226             scope => $prototype,
227             ),
228             );
229              
230 6         455 $bag->add_artifact(
231             store_array => Bolts::Artifact->new(
232             name => 'store_array',
233             blueprint => Bolts::Blueprint::Factory->new(
234             class => 'Bolts::Injector::Store::Array',
235             ),
236             infer => 'options',
237             scope => $prototype,
238             ),
239             );
240              
241 6         557 $bag->add_artifact(
242             store_hash => Bolts::Artifact->new(
243             name => 'store_hash',
244             blueprint => Bolts::Blueprint::Factory->new(
245             class => 'Bolts::Injector::Store::Hash',
246             ),
247             infer => 'options',
248             scope => $prototype,
249             ),
250             );
251              
252 6         275 $bag->finish_bag;
253              
254 6         220 return $bag->name->new;
255             }
256              
257              
258             has scope => (
259             is => 'ro',
260             isa => 'Object',
261             lazy_build => 1,
262             );
263              
264             sub _build_scope {
265 16     16   28 my $self = shift;
266              
267 16         540 my $singleton = Bolts::Scope::Singleton->new;
268 16         503 my $prototype = Bolts::Scope::Prototype->new;
269              
270 16         548 my $prototype_artifact = Bolts::Artifact->new(
271             name => 'prototype',
272             blueprint => Bolts::Blueprint::Literal->new(
273             value => $prototype,
274             ),
275             scope => $singleton,
276             );
277              
278 16         117 my $bag = Bolts::Bag->start_bag(
279             package => 'Bolts::Meta::Locator::Scope',
280             such_that_each => {
281             does => 'Bolts::Scope',
282             },
283             );
284              
285 16 50       74 return $bag->name->new if $bag->is_finished_bag;
286              
287 16         100 $bag->add_artifact(_ => $prototype_artifact);
288 16         716 $bag->add_artifact(prototype => $prototype_artifact);
289              
290 16         864 $bag->add_artifact(
291             singleton => Bolts::Artifact->new(
292             name => 'singleton',
293             blueprint => Bolts::Blueprint::Literal->new(
294             value => $singleton,
295             ),
296             scope => $singleton,
297             ),
298             );
299              
300 16         524 return $bag->name->new;
301             }
302              
303             1;
304              
305             __END__
306              
307             =pod
308              
309             =encoding UTF-8
310              
311             =head1 NAME
312              
313             Bolts::Meta::Locator - Standard meta locator for Bolts
314              
315             =head1 VERSION
316              
317             version 0.142930
318              
319             =head1 DESCRIPTION
320              
321             This provides the standard meta locator for Bolts. It may be extended by your application to add custom blueprints, scopes, injectors, inferrers, and other objects.
322              
323             =head1 ROLES
324              
325             =over
326              
327             =item *
328              
329             L<Bolts::Role::RootLocator>
330              
331             =back
332              
333             =head1 ATTRIBUTES
334              
335             =head2 root
336              
337             This returns the object itself for L<Bolts::Role::Locator> to use.
338              
339             =head2 blueprints
340              
341             This is a bag within the meta locator containing these blueprints.
342              
343             =head3 acquired
344              
345             This constructs artifacts by acquisition, via L<Bolts::Blueprint::Acquired>.
346              
347             =head3 given
348              
349             This constructs artifacts for injection by pulling values from passed parameters, via L<Bolts::Blueprint::Given>.
350              
351             =head3 literal
352              
353             This constructs artifacts using a value defined when the bag is defined, via L<Bolts::Blueprint::Literal>.
354              
355             =head3 built
356              
357             This constructs artifacts using a subroutine given when the bag is defined, via L<Bolts::Blueprint::Built>.
358              
359             =head3 build_injector
360              
361             This constructs artifacts for injection using a subroutine given when the bag is defined, via L<Bolts::Blueprint::BuiltInjector>.
362              
363             =head3 factory
364              
365             This constructs artifacts by calling a class method on a package name, via L<Bolts::Blueprint::Factory>.
366              
367             =head2 inference
368              
369             This is a nested array bag containing these inferrers. (Actually, just this inferrer so far.)
370              
371             =head3 moose
372              
373             This infers the dependencies a L<Moose> class has by examining the attributes on it's metaclass. This inferer only works with L<Bolts::Blueprint::Factory> blueprints.
374              
375             =head2 injector
376              
377             This is a nested bag containing dependency injector objects. It contains these injectors.
378              
379             =head3 parameter_name
380              
381             Injects by passing named parameters to the blueprint, via L<Bolts::Injector::Parameter::ByName>.
382              
383             =head3 parameter_position
384              
385             Injects by passing parameters by position to the blueprint, via L<Bolts::Injector::Parameter::ByPosition>.
386              
387             =head3 setter
388              
389             Injects by calling a setter method on the constructed artifact, via L<Bolts::Injector::Setter>.
390              
391             =head3 store_array
392              
393             Injects into an array reference by index or push, via L<Bolts::Injector::Store::Array>.
394              
395             =head3 store_hash
396              
397             Injects into a hash reference by key, via L<Bolts::Injector::Store::Hash>.
398              
399             =head2 scope
400              
401             Nested bag containing the predefined scopes.
402              
403             =head3 _
404              
405             This is the default scope, which is the same as L</prototype>.
406              
407             =head3 prototype
408              
409             This is the non-scope scope, which never caches a value and always causes it to constructed on each acquisition, via L<Bolts::Scope::Prototype>.
410              
411             =head3 singleton
412              
413             This scopes an artifact to last as long as the bag containing it, via L<Bolts::Scope::Singleton>.
414              
415             =head1 AUTHOR
416              
417             Andrew Sterling Hanenkamp <hanenkamp@cpan.org>
418              
419             =head1 COPYRIGHT AND LICENSE
420              
421             This software is copyright (c) 2014 by Qubling Software LLC.
422              
423             This is free software; you can redistribute it and/or modify it under
424             the same terms as the Perl 5 programming language system itself.
425              
426             =cut