File Coverage

blib/lib/Reflex/Event.pm
Criterion Covered Total %
statement 46 74 62.1
branch 11 26 42.3
condition 8 33 24.2
subroutine 9 14 64.2
pod 1 3 33.3
total 75 150 50.0


line stmt bran cond sub pod time code
1             package Reflex::Event;
2             $Reflex::Event::VERSION = '0.100';
3 13     13   30753 use Moose;
  13         23  
  13         67  
4 13     13   54891 use Scalar::Util qw(weaken);
  13         22  
  13         2236  
5              
6             # Class scoped storage.
7             # Each event class has a set of attribute names.
8             # There's no reason to calculate them every _clone() call.
9             my %attribute_names;
10              
11             has _name => (
12             is => 'ro',
13             isa => 'Str',
14             default => 'generic',
15             );
16              
17             has _emitters => (
18             is => 'ro',
19             isa => 'ArrayRef[Any]',
20             traits => ['Array'],
21             required => 1,
22             handles => {
23             get_first_emitter => [ 'get', 0 ],
24             get_last_emitter => [ 'get', -1 ],
25             get_all_emitters => 'elements',
26             }
27             );
28              
29             sub _get_attribute_names {
30 0     0   0 my $self = shift();
31             return(
32             $attribute_names{ ref $self } ||= [
33 0   0     0 map { $_->name() }
  0         0  
34             $self->meta()->get_all_attributes()
35             ]
36             );
37             }
38              
39             #sub BUILD {
40             # my $self = shift();
41             #
42             # # After build, weaken any emitters passed in.
43             # #my $emitters = $self->_emitters();
44             # #weaken($_) foreach @$emitters;
45             #}
46              
47             sub push_emitter {
48 34     34 0 52 my ($self, $item) = @_;
49              
50 13 50   13   65 use Carp qw(confess); confess "wtf" unless defined $item;
  13         16  
  13         7096  
  34         82  
51              
52 34         837 my $emitters = $self->_emitters();
53 34         128 push @$emitters, $item;
54             #weaken($emitters->[-1]);
55             }
56              
57             sub _headers {
58 0     0   0 my $self = shift();
59             return (
60 0         0 map { "-" . substr($_,1), $self->$_() }
61             grep /^_/,
62 0         0 @{ $self->_get_attribute_names() },
  0         0  
63             );
64             }
65              
66             sub _body {
67 0     0   0 my $self = shift();
68             return (
69 0         0 map { $_, $self->$_() }
70             grep /^[^_]/,
71 0         0 @{ $self->_get_attribute_names() },
  0         0  
72             );
73             }
74              
75             sub make_event_cloner {
76 47     47 0 103 my $class = shift();
77              
78 47         189 my $class_meta = $class->meta();
79              
80 47         636 my @fetchers;
81 47         163 foreach my $attribute_name (
82 127         1780 map { $_->name } $class_meta->get_all_attributes
83             ) {
84 127         147 my $override_name = $attribute_name;
85 127         312 $override_name =~ s/^_/-/;
86              
87 127 100       325 next if $attribute_name eq '_emitters';
88              
89 80         400 push @fetchers, (
90             join ' ', (
91             "\"$attribute_name\" => (",
92             "(exists \$override_args{\"$override_name\"})",
93             "? \$override_args{\"$override_name\"}",
94             ": \$self->$attribute_name()",
95             ")",
96             )
97             );
98             }
99              
100 47         274 my $cloner_code = join ' ', (
101             'sub {',
102             'my ($self, %override_args) = @_;',
103             'my %clone_args = ( ',
104             join(',', @fetchers),
105             ');',
106             'my $type = $override_args{"-type"} || ref($self);',
107             'my $emitters = $self->_emitters() || [];',
108             '$type->new(%clone_args, _emitters => [ @$emitters ]);',
109             '}'
110             );
111              
112 47 50 33 10   5931 my $cloner = eval $cloner_code;
  10 0 33 9   18  
  10 50 33 5   24  
  10 50 33 10   42  
  10 0 33 0   188  
  10 0 33     190  
  9 50 33     79  
  9 50 50     67  
  9 50 0     59  
  9   0     274  
  9         284  
  5         20  
  5         36  
  5         31  
  5         125  
  5         134  
  10         29  
  10         162  
  10         77  
  10         342  
  10         340  
  0            
  0            
  0            
  0            
  0            
113 47 50       174 if ($@) {
114 0         0 die(
115             "cloner compile error: $@\n",
116             "cloner: $cloner_code\n"
117             );
118             }
119              
120 47         175 $class_meta->add_method( _clone => $cloner );
121             }
122              
123             # Override Moose's dump().
124             sub dump {
125 0     0 1   my $self = shift;
126              
127 0           my $dump = "=== $self ===\n";
128 0           my %clone = ($self->_headers(), $self->_body());
129 0           foreach my $k (sort keys %clone) {
130 0   0       $dump .= " $k: " . ($clone{$k} // '(undef)') . "\n";
131 0 50         if ($k eq '-emitters') {
132 0           my @emitters = $self->get_all_emitters();
133 0           for my $i (0..$#emitters) {
134 0           $dump .= " emitter $i: $emitters[$i]\n";
135             }
136             }
137             }
138              
139             # No newline so we get line numbers.
140 0           $dump .= "===";
141              
142 0           return $dump;
143             }
144              
145             __PACKAGE__->make_event_cloner;
146             __PACKAGE__->meta->make_immutable;
147              
148             1;
149              
150             __END__
151              
152             =pod
153              
154             =encoding UTF-8
155              
156             =for :stopwords Rocco Caputo
157              
158             =head1 VERSION
159              
160             This document describes version 0.100, released on April 02, 2017.
161              
162             =for Pod::Coverage make_event_cloner push_emitter
163              
164             =head1 SEE ALSO
165              
166             Please see those modules/websites for more information related to this module.
167              
168             =over 4
169              
170             =item *
171              
172             L<Reflex|Reflex>
173              
174             =back
175              
176             =head1 BUGS AND LIMITATIONS
177              
178             You can make new bug reports, and view existing ones, through the
179             web interface at L<http://rt.cpan.org/Public/Dist/Display.html?Name=Reflex>.
180              
181             =head1 AUTHOR
182              
183             Rocco Caputo <rcaputo@cpan.org>
184              
185             =head1 COPYRIGHT AND LICENSE
186              
187             This software is copyright (c) 2017 by Rocco Caputo.
188              
189             This is free software; you can redistribute it and/or modify it under
190             the same terms as the Perl 5 programming language system itself.
191              
192             =head1 AVAILABILITY
193              
194             The latest version of this module is available from the Comprehensive Perl
195             Archive Network (CPAN). Visit L<http://www.perl.com/CPAN/> to find a CPAN
196             site near you, or see L<https://metacpan.org/module/Reflex/>.
197              
198             =head1 DISCLAIMER OF WARRANTY
199              
200             BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
201             FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT
202             WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER
203             PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND,
204             EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
205             IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
206             PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
207             SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME
208             THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION.
209              
210             IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
211             WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
212             REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE
213             TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR
214             CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
215             SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
216             RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
217             FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
218             SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
219             DAMAGES.
220              
221             =cut