File Coverage

lib/DataFlow/Proc.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package DataFlow::Proc;
2              
3 1     1   1722 use strict;
  1         1  
  1         26  
4 1     1   5 use warnings;
  1         1  
  1         32  
5              
6             # ABSTRACT: A data processor class
7              
8             our $VERSION = '1.121830'; # VERSION
9              
10 1     1   368 use Moose;
  0            
  0            
11             with 'DataFlow::Role::Processor';
12             with 'DataFlow::Role::Dumper';
13              
14             use Moose::Autobox;
15             use DataFlow::Types qw(ProcessorSub ProcPolicy);
16              
17             use namespace::autoclean;
18             use Scalar::Util qw/reftype/;
19             use Moose::Util::TypeConstraints 1.01;
20              
21             with 'MooseX::OneArgNew' => { 'type' => 'CodeRef', 'init_arg' => 'p', };
22              
23             ################################################################################
24              
25             has 'allows_undef_input' => (
26             'is' => 'ro',
27             'isa' => 'Bool',
28             'lazy' => 1,
29             'default' => 0,
30             );
31              
32             has 'deref' => (
33             'is' => 'ro',
34             'isa' => 'Bool',
35             'lazy' => 1,
36             'default' => 0,
37             );
38              
39             has 'policy' => (
40             'is' => 'ro',
41             'isa' => 'ProcPolicy',
42             'coerce' => 1,
43             'lazy' => 1,
44             'builder' => '_policy',
45             'init_arg' => 'policy',
46             );
47              
48             has 'p' => (
49             'is' => 'ro',
50             'isa' => 'ProcessorSub',
51             'required' => 1,
52             'coerce' => 1,
53             'lazy' => 1,
54             'builder' => '_build_p',
55             'documentation' =>
56             'Code reference that returns the result of processing one single item',
57             );
58              
59             sub _build_p {
60             return;
61             }
62              
63             sub _policy {
64             return 'ProcessInto';
65             }
66              
67             sub _process_one {
68             my ( $self, $item ) = @_;
69             return $self->policy->apply( $self->p, $item );
70             }
71              
72             sub _deref {
73             my $value = shift;
74             my $ref = reftype($value) || '';
75             return ${$value} if $ref eq 'SCALAR';
76             return @{$value} if $ref eq 'ARRAY';
77             return %{$value} if $ref eq 'HASH';
78             return $value->() if $ref eq 'CODE';
79             return $value;
80             }
81              
82             sub process {
83             my ( $self, $item ) = @_;
84              
85             $self->prefix_dumper( $self->has_name ? $self->name . ' <<' : '<<', $item )
86             if $self->dump_input;
87             return () unless ( $self->allows_undef_input || defined($item) );
88              
89             my @result =
90             $self->deref
91             ? @{ [ $self->_process_one($item) ]->map( sub { _deref($_) } ) }
92             : $self->_process_one($item);
93              
94             $self->prefix_dumper( $self->has_name ? $self->name . ' >>' : '>>',
95             @result )
96             if $self->dump_output;
97             return @result;
98             }
99              
100             __PACKAGE__->meta->make_immutable;
101              
102             1;
103              
104              
105              
106             =pod
107              
108             =encoding utf-8
109              
110             =head1 NAME
111              
112             DataFlow::Proc - A data processor class
113              
114             =head1 VERSION
115              
116             version 1.121830
117              
118             =head1 SYNOPSIS
119              
120             use DataFlow::Proc;
121              
122             my $uc = DataFlow::Proc->new( p => sub { uc } );
123              
124             my @res = $uc->process( 'something' );
125             # @res == qw/SOMETHING/;
126              
127             my @res = $uc->process( [qw/aaa bbb ccc/] );
128             # @res == [qw/AAA BBB CCC/];
129              
130             Or
131              
132             my $uc_deref = DataFlow::Proc->new(
133             deref => 1,
134             p => sub { uc }
135             );
136              
137             my @res = $uc_deref->process( [qw/aaa bbb ccc/] );
138             # @res == qw/AAA BBB CCC/;
139              
140             =head1 DESCRIPTION
141              
142             This is a L<Moose> based class that provides the idea of a processing step in
143             a data-flow. It attemps to be as generic and unassuming as possible, in order
144             to provide flexibility for implementors to make their own specialized
145             processors as they see fit.
146              
147             Apart from atribute accessors, an object of the type C<DataFlow::Proc> will
148             provide only a single method, C<process()>, which will process a single
149             scalar.
150              
151             =head1 ATTRIBUTES
152              
153             =head2 name
154              
155             [Str] A descriptive name for the dataflow. (OPTIONAL)
156              
157             =head2 allows_undef_input
158              
159             [Bool] It controls whether C<< $self->p->() >> will accept C<undef> as input
160             or if DataFlow::Proc will filter those out. (DEFAULT = false)
161              
162             =head2 deref
163              
164             [Bool] Signals whether the result of the processing will be de-referenced
165             upon output or if DataFlow::Proc will preserve the original reference.
166             (DEFAULT = false)
167              
168             =head2 dump_input
169              
170             [Bool] Dumps the input parameter to STDERR before processing. See
171             L<DataFlow::Role::Dumper>. (DEFAULT = false)
172              
173             =head2 dump_output
174              
175             [Bool] Dumps the results to STDERR after processing. See
176             L<DataFlow::Role::Dumper>. (DEFAULT = false)
177              
178             =head2 p
179              
180             [CodeRef] The actual work horse for this class. It is treated as a function,
181             not as a method, as in:
182              
183             my $proc = DataFlow::Proc->new( p => sub { ucfirst } );
184              
185             The sub referenced by C<p> is run with a localized version the special
186             variable C<< $_ >>, containing the value of the data to be processed.
187              
188             It only makes sense to access C<$self> when one is sub-classing DataFlow::Proc
189             and adding new attibutes or methods, in which case one can do as below:
190              
191             package MyProc;
192              
193             use Moose;
194             extends 'DataFlow::Proc';
195              
196             has 'x_factor' => ( isa => 'Int' );
197              
198             sub _build_p {
199             my $self = shift;
200             return sub { $_ * int( rand( $self->x_factor ) ) };
201             }
202              
203             package main;
204              
205             my $proc = MyProc->new( x_factor => 5 );
206              
207             This sub will be called in array context. There is no other restriction on
208             what this code reference can or should do. (REQUIRED)
209              
210             =head1 METHODS
211              
212             =head2 process
213              
214             Processes one single scalar (or anything else that can be passed in on scalar,
215             such as references or globs), and returns the application of the function
216             C<< $self->p->() >> over the item.
217              
218             =head1 SEE ALSO
219              
220             Please see those modules/websites for more information related to this module.
221              
222             =over 4
223              
224             =item *
225              
226             L<DataFlow|DataFlow>
227              
228             =back
229              
230             =head1 AUTHOR
231              
232             Alexei Znamensky <russoz@cpan.org>
233              
234             =head1 COPYRIGHT AND LICENSE
235              
236             This software is copyright (c) 2011 by Alexei Znamensky.
237              
238             This is free software; you can redistribute it and/or modify it under
239             the same terms as the Perl 5 programming language system itself.
240              
241             =head1 BUGS AND LIMITATIONS
242              
243             You can make new bug reports, and view existing ones, through the
244             web interface at L<http://rt.cpan.org>.
245              
246             =head1 DISCLAIMER OF WARRANTY
247              
248             BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
249             FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT
250             WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER
251             PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND,
252             EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
253             IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
254             PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
255             SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME
256             THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION.
257              
258             IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
259             WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
260             REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE
261             TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR
262             CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
263             SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
264             RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
265             FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
266             SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
267             DAMAGES.
268              
269             =cut
270              
271              
272             __END__
273              
274