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.143171';
3             # ABSTRACT: Standard meta locator for Bolts
4              
5 11     11   49 use Moose;
  11         14  
  11         62  
6              
7             with qw( Bolts::Role::RootLocator );
8              
9 11     11   54629 use Bolts::Artifact;
  11         3289  
  11         416  
10 11     11   5581 use Bolts::Artifact::Thunk;
  11         2874  
  11         384  
11 11     11   4949 use Bolts::Bag;
  11         2788  
  11         391  
12              
13 11     11   73 use Bolts::Blueprint::Built;
  11         16  
  11         191  
14 11     11   4512 use Bolts::Blueprint::Factory;
  11         3002  
  11         378  
15 11     11   111 use Bolts::Blueprint::Given;
  11         17  
  11         334  
16 11     11   47 use Bolts::Blueprint::Literal;
  11         15  
  11         182  
17              
18 11     11   5118 use Bolts::Injector::Parameter::ByName;
  11         2997  
  11         411  
19              
20 11     11   5181 use Bolts::Scope::Prototype;
  11         2773  
  11         352  
21 11     11   4168 use Bolts::Scope::Singleton;
  11         3093  
  11         341  
22              
23 11     11   65 use Class::Load;
  11         14  
  11         10351  
24              
25              
26 325     325 1 508 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 19     19   46 my $self = shift;
37              
38 19         151 my $bp = Bolts::Bag->start_bag(
39             package => 'Bolts::Meta::Locator::Blueprint',
40             such_that_each => {
41             does => 'Bolts::Blueprint',
42             },
43             );
44              
45 19 100       137 return $bp->name->new if $bp->is_finished_bag;
46              
47             $bp->add_artifact(
48             acquired => Bolts::Artifact::Thunk->new(
49             thunk => sub {
50 38     38   83 my ($self, $bag, %o) = @_;
51 38         112 Class::Load::load_class('Bolts::Blueprint::Acquired');
52 38         3577 Bolts::Blueprint::Acquired->new(%o);
53             },
54 11         486 ),
55             );
56              
57             $bp->add_artifact(
58             given => Bolts::Artifact::Thunk->new(
59             thunk => sub {
60 112     112   204 my ($self, $bag, %o) = @_;
61 112         272 Class::Load::load_class('Bolts::Blueprint::Given');
62 112         5341 Bolts::Blueprint::Given->new(%o);
63             },
64 11         786 ),
65             );
66              
67             $bp->add_artifact(
68             literal => Bolts::Artifact::Thunk->new(
69             thunk => sub {
70 42     42   91 my ($self, $bag, %o) = @_;
71 42         106 Class::Load::load_class('Bolts::Blueprint::Literal');
72 42         2008 Bolts::Blueprint::Literal->new(%o);
73             },
74 11         821 ),
75             );
76              
77             $bp->add_artifact(
78             built => Bolts::Artifact::Thunk->new(
79             thunk => sub {
80 46     46   110 my ($self, $bag, %o) = @_;
81 46         125 Class::Load::load_class('Bolts::Blueprint::Built');
82 46         2330 Bolts::Blueprint::Built->new(%o);
83             },
84 11         787 ),
85             );
86              
87             $bp->add_artifact(
88             built_injector => Bolts::Artifact::Thunk->new(
89             thunk => sub {
90 4     4   8 my ($self, $bag, %o) = @_;
91 4         13 Class::Load::load_class('Bolts::Blueprint::BuiltInjector');
92 4         723 Bolts::Blueprint::BuiltInjector->new(%o);
93             },
94 11         738 ),
95             );
96              
97             $bp->add_artifact(
98             factory => Bolts::Artifact::Thunk->new(
99             thunk => sub {
100 24     24   56 my ($self, $bag, %o) = @_;
101 24         66 Class::Load::load_class('Bolts::Blueprint::Factory');
102 24         1204 Bolts::Blueprint::Factory->new(%o);
103             },
104 11         810 ),
105             );
106              
107             $bp->add_artifact(
108             parent_bag => Bolts::Artifact::Thunk->new(
109             thunk => sub {
110 2     2   6 my ($self, $bag, %o) = @_;
111 2         7 Class::Load::load_class('Bolts::Blueprint::ParentBag');
112 2         359 Bolts::Blueprint::ParentBag->new(%o);
113             },
114 11         792 ),
115             );
116              
117 11         451 $bp->finish_bag;
118              
119 11         570 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   13 my $self = shift;
131              
132 6         158 my $singleton = $self->scope->singleton->get($self->scope);
133              
134             return [
135 6         202 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   23 my $self = shift;
154              
155 12         301 my $prototype = $self->scope->prototype->get($self->scope);
156              
157 12         419 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         84 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       51 return $bag->name->new if $bag->is_finished_bag;
205              
206 6         38 $bag->add_artifact( parameter_name => $parameter_name );
207            
208 6         399 $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         431 $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         389 $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         399 $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         233 $bag->finish_bag;
253              
254 6         196 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 19     19   38 my $self = shift;
266              
267 19         603 my $singleton = Bolts::Scope::Singleton->new;
268 19         574 my $prototype = Bolts::Scope::Prototype->new;
269              
270 19         602 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 19         150 my $bag = Bolts::Bag->start_bag(
279             package => 'Bolts::Meta::Locator::Scope',
280             such_that_each => {
281             does => 'Bolts::Scope',
282             },
283             );
284              
285 19 50       84 return $bag->name->new if $bag->is_finished_bag;
286              
287 19         118 $bag->add_artifact(_ => $prototype_artifact);
288 19         847 $bag->add_artifact(prototype => $prototype_artifact);
289              
290 19         1009 $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 19         643 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.143171
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