File Coverage

blib/lib/Bolts/Meta/Class/Trait/Bag.pm
Criterion Covered Total %
statement 30 41 73.1
branch 12 18 66.6
condition 6 12 50.0
subroutine 33 36 91.6
pod 3 3 100.0
total 84 110 76.3


line stmt bran cond sub pod time code
1             package Bolts::Meta::Class::Trait::Bag;
2             $Bolts::Meta::Class::Trait::Bag::VERSION = '0.142930';
3             # ABSTRACT: Metaclass role for Bolts-built bags
4              
5 8     36   4182 use Moose::Role;
  8         14  
  8         145  
6              
7 8     36   34337 use Safe::Isa;
  8         17  
  8         1033  
8 8     36   66 use Scalar::Util qw( reftype );
  8         17  
  8         3707  
9              
10              
11             has artifacts => (
12             is => 'ro',
13             isa => 'ArrayRef',
14             required => 1,
15             default => sub { [] },
16             );
17              
18              
19             has such_that_isa => (
20             is => 'rw',
21             isa => 'Moose::Meta::TypeConstraint',
22             predicate => 'has_such_that_isa',
23             );
24              
25              
26             has such_that_does => (
27             is => 'rw',
28             isa => 'Moose::Meta::TypeConstraint',
29             predicate => 'has_such_that_does',
30             );
31              
32              
33             sub is_finished_bag {
34 47     47 1 804 my $meta = shift;
35 47         201 return $meta->is_immutable;
36             }
37              
38              
39             sub add_artifact {
40 177     177 1 353 my ($meta, $method, $value, $such_that) = @_;
41            
42 177 100 100     7058 if (!defined $such_that and ($meta->has_such_that_isa
      33        
43             or $meta->has_such_that_does)) {
44 137         164 $such_that = {};
45 137 100       4671 $such_that->{isa} = $meta->such_that_isa
46             if $meta->has_such_that_isa;
47 137 100       4608 $such_that->{does} = $meta->such_that_does
48             if $meta->has_such_that_does;
49             }
50              
51 177 100 66     539 if ($value->$_does('Bolts::Role::Artifact')) {
    100          
52 175 100       10397 $value->such_that($such_that) if $such_that;
53 175     359   1054 $meta->add_method($method => sub { $value });
  359     359   1178  
        84      
        359      
        474      
        474      
        260      
        387      
        547      
        474      
        629      
        486      
        359      
        359      
        327      
        359      
        355      
        327      
        161      
        117      
        117      
        117      
        117      
        319      
54             }
55              
56             elsif (defined reftype($value) and reftype($value) eq 'CODE') {
57 1         38 my $thunk = Bolts::Artifact::Thunk->new(
58             %$such_that,
59             thunk => $value,
60             );
61              
62 1     2   5 $meta->add_method($method => sub { $thunk });
  2         5  
63             }
64              
65             else {
66             # TODO It would be better to assert the validity of the checks on
67             # the value immediately.
68              
69             my $thunk = Bolts::Artifact::Thunk->new(
70             %$such_that,
71 2     4   5 thunk => sub { $value },
72 1         52 );
73              
74 1     2   7 $meta->add_method($method => sub { $thunk });
  2         5  
75             }
76              
77             }
78              
79              
80             sub finish_bag {
81 21     23 1 423 my ($meta) = @_;
82              
83 21         142 $meta->make_immutable(
84             replace_constructor => 1,
85             replace_destructor => 1,
86             );
87              
88 21         111497 return $meta;
89             }
90              
91             sub _wrap_method_in_such_that_check {
92 0     0     my ($meta, $code, $such_that) = @_;
93              
94 0           my $wrapped;
95 0 0 0       if (defined $such_that->{isa} or defined $such_that->{does}) {
96             $wrapped = sub {
97 0     0     my $result = $code->(@_);
98              
99 0 0         $such_that->{isa}->assert_valid($result)
100             if defined $such_that->{isa};
101              
102 0 0         $such_that->{does}->assert_valid($result)
103             if defined $such_that->{does};
104              
105 0           return $result;
106 0           };
107             }
108             else {
109             $wrapped = sub {
110 0     0     return scalar $code->(@_);
111 0           };
112             }
113              
114 0           return $wrapped;
115             }
116              
117              
118             1;
119              
120             __END__
121              
122             =pod
123              
124             =encoding UTF-8
125              
126             =head1 NAME
127              
128             Bolts::Meta::Class::Trait::Bag - Metaclass role for Bolts-built bags
129              
130             =head1 VERSION
131              
132             version 0.142930
133              
134             =head1 DESCRIPTION
135              
136             While a bag may be any kind of object, this metaclass role on a bag provides some helpful utilities for creating and managing bags.
137              
138             =head1 ATTRIBUTES
139              
140             =head2 artifacts
141              
142             These are the artifacts that have been added to this bag.
143              
144             =head2 such_that_isa
145              
146             This is a L<Moose::Meta::TypeConstraint> to apply to the L<Bolts::Artifact/isa_type> of all contained artifacts.
147              
148             =head2 such_that_does
149              
150             This is a L<Moose::Meta::TypeConstraint> to apply to the L<Bolts::Artifact/does_type> of all contained artifacts.
151              
152             =head1 METHODS
153              
154             =head2 is_finished_bag
155              
156             my $finished = $meta->is_finished_bag;
157              
158             This is used to determine if a bag's definition has already been performed and completed. At this time, it's just a synonym for L<Class::MOP::Class/is_immutable>.
159              
160             =head2 add_artifact
161              
162             $meta->add_artifact(name => $artifact, {
163             isa => $isa_type,
164             does => $does_type,
165             });
166              
167             Adds an artifact method to the bag with the given C<name>. The C<$artifact> may be an instance of L<Bolts::Role::Artifact>, a code reference to used to define a L<Bolts::Artifact::Thunk> or just another value, which will be wrapped in an anonymous sub and turned into a L<Bolts::Artifact::Thunk>.
168              
169             The C<isa> and C<does> will be applied to the artifact as appropriate.
170              
171             =head2 finish_bag
172              
173             $meta->finish_bag;
174              
175             This completes the bag building process and marks the Moose object as immutable. Aft this is called, L</is_finished_bag> returns true.
176              
177             =head1 AUTHOR
178              
179             Andrew Sterling Hanenkamp <hanenkamp@cpan.org>
180              
181             =head1 COPYRIGHT AND LICENSE
182              
183             This software is copyright (c) 2014 by Qubling Software LLC.
184              
185             This is free software; you can redistribute it and/or modify it under
186             the same terms as the Perl 5 programming language system itself.
187              
188             =cut