File Coverage

blib/lib/List/Filter/Dispatcher.pm
Criterion Covered Total %
statement 58 66 87.8
branch n/a
condition 1 3 33.3
subroutine 14 16 87.5
pod 7 7 100.0
total 80 92 86.9


line stmt bran cond sub pod time code
1             package List::Filter::Dispatcher;
2 4     4   22 use base qw( Class::Base );
  4         7  
  4         616  
3              
4             =head1 NAME
5              
6             List::Filter::Dispatcher -
7              
8             =head1 SYNOPSIS
9              
10             use List::Filter::Dispatcher;
11             my $dispatcher = List::Filter::Dispatcher->new(
12             { plugin_root => 'List::Filter::Filters',
13             plugin_exceptions => 'List::Filter::Filters::Ext::Nogoodnik',
14             } );
15             my $aref_out = $dispatcher->apply( $filter, $aref_in );
16              
17             =head1 DESCRIPTION
18              
19             The Dispatcher object is told where to look for modules that
20             contain the methods that can apply a L filter.
21             During it's init phase the dispatcher does the necessary requires
22             of each of those method-supplying modules, which must be designed
23             to export these methods to the Dispatcher's namespace.
24              
25             It's expected that when a new Filter object (or one of it's
26             inheritors) is created, it will be assigned a dispatcher so that
27             it will be able to execute the filter's methods. See
28             L.
29              
30              
31             =head2 MOTIVATION
32              
33             This is part of an extension mechanism to allow the creation of
34             additional filter filter methods that the existing code framework
35             will be able to use without modification.
36              
37             One advantage of this approach is that each filter object has a
38             default method (accessed via the L method), and yet it can
39             be applied with a different method if that seems desireable.
40              
41             For example: an "omit" filter could be inverted to display
42             only the items that are usually omitted.
43              
44             See L<"List::Filter::Project/Extension mechanisms"> for
45             instructions on writing methods, and creating filters that use
46             them.
47              
48             =head2 METHODS
49              
50             =over
51              
52             =cut
53              
54 4     4   49 use 5.8.0;
  4         14  
  4         255  
55 4     4   24 use strict;
  4         8  
  4         158  
56 4     4   22 use warnings;
  4         7  
  4         187  
57             my $DEBUG = 0;
58 4     4   21 use Carp;
  4         8  
  4         256  
59 4     4   20 use Data::Dumper;
  4         5  
  4         232  
60 4     4   21 use Hash::Util qw(lock_keys unlock_keys);
  4         8  
  4         22  
61 4     4   3258 use Module::List qw(list_modules);
  4         189319  
  4         280  
62              
63 4     4   3745 use Module::List::Pluggable qw( list_modules_under import_modules );
  4         7182  
  4         2169  
64              
65             our $VERSION = '0.01';
66              
67             =item new
68              
69             Instantiates a new List::Filter::Dispatcher object.
70              
71             Takes an optional hashref as an argument, with named fields
72             identical to the names of the object attributes:
73              
74             =over
75              
76             =item plugin_root
77              
78             The location to look for the "plugins" that define the actual
79             "methods" that tasks are dispatched to.
80              
81             =item plugin_exceptions
82              
83             A list of modules in the plugin_root that will be ignored.
84              
85             Note: if you absolutely must use inheritence to create a variant
86             of an existing plugin, the original parent class should be
87             entered in this list to avoid namespace collisions.
88              
89             =back
90              
91             =cut
92              
93             # Note:
94             # "new" is inherited from Class::Base.
95             # It calls the following "init" routine automatically.
96              
97             =item init
98              
99             Initialize object attributes and then lock them down to prevent
100             accidental creation of new ones.
101              
102             =cut
103              
104             sub init {
105 29     29 1 1169 my $self = shift;
106 29         61 my $args = shift;
107 29         48 unlock_keys( %{ $self } );
  29         119  
108              
109             # define new attributes
110             my $attributes = {
111             plugin_root => $args->{ plugin_root },
112 29         246 };
113              
114             # add attributes to object
115 29         46 my @fields = (keys %{ $attributes });
  29         115  
116 29         65 @{ $self }{ @fields } = @{ $attributes }{ @fields }; # hash slice
  29         88  
  29         61  
117              
118 29         87 $self->do_require_of_plugins;
119              
120 29         74091 lock_keys( %{ $self } );
  29         192  
121 29         513 return $self;
122             }
123              
124              
125             =item do_require_of_plugins
126              
127             An internally used routine that loads all of the subs defined in
128             all of the plugins/extensions found in perl's module namespace
129             at or under the "plugin_root" location.
130              
131             Returns: the number of sucessfully loaded plugin modules.
132              
133             =cut
134              
135             sub do_require_of_plugins {
136 29     29 1 53 my $self = shift;
137 29         90 my $plugin_root = $self->plugin_root;
138 29         93 my $plugin_exceptions = $self->plugin_exceptions;
139              
140             # See Module::List::Pluggable
141 29         190 import_modules( $plugin_root, {
142             exceptions => $plugin_exceptions,
143             });
144             }
145              
146              
147             =item apply
148              
149             Applies the filter object, typically acting as a filter.
150              
151             Inputs:
152             (1) filter object (note: contains an array of patterns)
153             (2) aref of input items to be operated on
154             (3) an options hash reference:
155              
156             Supported option(s):
157              
158             "method" -- routine to use to apply filter to input items
159             (defaults to method specified inside the filter).
160              
161             Return:
162             aref of output items
163              
164             Note:
165             The options href is also passed through to the "method" routine.
166              
167             =cut
168              
169             sub apply {
170 1     1 1 15 my $self = shift;
171 1         2 my $filter = shift;
172 1         2 my $items = shift;
173 1         2 my $opt = shift;
174              
175 1   33     10 my $method = $opt->{ method } || $filter->method;
176              
177 1         7 my $output_aref = $self->$method( $filter, $items, $opt );
178 1         313 return $output_aref;
179             }
180              
181             =back
182              
183             =head2 accessors (setters and getters)
184              
185             Note: because of the oddities of the current architecture,
186             accessors must be provided for any fields needed by either the
187             Filter or the Transform routines, since those are imported into
188             the Dispatcher namespace, they become Dispatcher methods.
189              
190             I'm making an effort to document them here, for that reason
191             (though in general I think they should be avoided, period).
192              
193             =over
194              
195             =item plugin_root
196              
197             Getter for object attribute plugin_root
198              
199             =cut
200              
201             sub plugin_root {
202 29     29 1 37 my $self = shift;
203 29         67 my $plugin_root = $self->{ plugin_root };
204 29         64 return $plugin_root;
205             }
206              
207             =item set_plugin_root
208              
209             Setter for object attribute set_plugin_root
210              
211             =cut
212              
213             sub set_plugin_root {
214 0     0 1 0 my $self = shift;
215 0         0 my $plugin_root = shift;
216 0         0 $self->{ plugin_root } = $plugin_root;
217 0         0 return $plugin_root;
218             }
219              
220              
221              
222             =item plugin_exceptions
223              
224             Getter for object attribute plugin_exceptions
225              
226             =cut
227              
228             sub plugin_exceptions {
229 29     29 1 40 my $self = shift;
230 29         53 my $plugin_exceptions = $self->{ plugin_exceptions };
231 29         53 return $plugin_exceptions;
232             }
233              
234             =item set_plugin_exceptions
235              
236             Setter for object attribute set_plugin_exceptions
237              
238             =cut
239              
240             sub set_plugin_exceptions {
241 0     0 1   my $self = shift;
242 0           my $plugin_exceptions = shift;
243 0           $self->{ plugin_exceptions } = $plugin_exceptions;
244 0           return $plugin_exceptions;
245             }
246              
247              
248             1;
249              
250             =head1 SEE ALSO
251              
252             L
253             L
254              
255             =head1 AUTHOR
256              
257             Joseph Brenner, Edoom@kzsu.stanford.eduE
258              
259             =head1 COPYRIGHT AND LICENSE
260              
261             Copyright (C) 2007 by Joseph Brenner
262              
263             This library is free software; you can redistribute it and/or modify
264             it under the same terms as Perl itself, either Perl version 5.8.2 or,
265             at your option, any later version of Perl 5 you may have available.
266              
267             =head1 BUGS
268              
269             None reported... yet.
270              
271             =cut