NAME
Data::Tubes::Plugin::Plumbing
DESCRIPTION
This module contains tubes factories for handling general plumbing requirements, e.g. put some other tubes in a sequence.
FUNCTIONS
- dispatch
-
my $tube = dispatch(%args); # OR my $tube = dispatch(\%args);
this function decides a sub-tube to use for dispatching a specific record. The selection of the sub-tube is performed through two different mechanisms:
- -
-
first, a selector function is applied to the input record, optionally defaulting to a configurable value. This selector is a string that MUST uniquely identify the output tube where the record should be dispatched;
- -
-
then, if the tube associated to the selector is already known, it will be used for the dispatching. Otherwise, a factory will be used to get a new handler tube for the specific selector, if possible.
The arguments passed through
%args
allow you to define the selector and the factory in a flexible way. Available options are:default
-
this allows defining the default selection key when none is available (i.e. it would be the undefined value). If set to an
undef
value, lack of a selector will throw an exception. Defaults toundef
; factory
-
set a sub reference to generate new tubes when needed. The factory function will be fed with the specific selection key as the first argument, and the record as the second argument, and it is supposed to return a valid tube (although it might throw an exception by itself, of course);
handlers
-
this is a quick way to set a simple factory that just returns elements from a hash reference (that is passed as value). If this is used, every key that is not present in the hash will throw an exception. If
factory
is present, this field will be ignored; key
-
this is a quick way to specify a selector function. It points to either a string/integer, or an array containing a sequence of strings/integers; these items will be used to access the provided
$record
in a "visit" that uses an item at each step. Example:$record = {aref => [1, 2, {foo => 'bar'}]}; @key = qw< aref 2 foo >; # this will select 'bar' above
If the option
selector
is passed, this field will be ignored; name
-
set a name for the dispatcher, might be useful while debugging if you plan to use more than one dispatcher;
selector
-
set to a subroutine reference that will be passed the input record and SHOULD provide a string back, that will uniquely identify a tube.
One between
selector
orkey
MUST be provided. One betweenfactory
andhandlers
MUST be provided. - logger
-
my $tube = logger(%args); # OR my $tube = logger(\%args);
this function generates a tube that is useful for logging things. You can pass the following arguments:
loglevel
-
the level where the logging should happen. See Log::Log4perl::Tiny for the available ones. Due to a current restriction in Log::Log4perl::Tiny (as of version 1.2.7), you MUST pass a numeric value and you cannot pass the name of a log level (this will likely change in the future);
name
-
the name assigned to the logger tube, might be useful while debugging;
target
-
a facility to isolate part of the target record and/or produce a message suitable for logging.
If not provided or undefined (which is the default), the whole input record will be passed to the logger function. This is probably what you don't want in the vast majority of cases, as you will only see a strange address printed out. Works fine if the input record is something printable, anyway.
The most flexible thing that you can pass is a sub reference. This will receive the input record, and SHOULD return back a string that will be printed in the log stream.
You can also provide either a string or a sequence of strings in an array reference. In this case, the record will be visited using these keys, much in the same way as described for "dispatch" above. Again, you should be pretty sure that the leaf value found after this traversal is something meaningful for printing.
The generated tube always returns back the input record, unchanged.
- sequence
-
my $tube = sequence(%args); # OR my $tube = sequence(\%args);
this function takes a sequence of tubes (i.e. functions that are compliant with the tube definition) and returns a tube that provides serialization of the operations, in the order as the passed list.
The returned tube is such that it will always return an iterator back (in particular, it will return two elements, the first is the string
iterator
and the second is an iterator sub reference).Arguments can be passed through a single reference to a hash, or as a sequence of key/value pairs. The following options are supported:
name
-
set a name for the sequence, which might come handy when debugging. Defaults to
sequence
; logger
-
can be optionally set to a function that will be called for each input record, being passed the record itself and a reference to the hash of arguments. Use this if you want to do some logging, ignore otherwise;
tubes
-
an array reference containing the list of tubes part of the sequence. These can be either direct tubes (i.e. references to subroutines) or definitions suitable for calling
tube
in Data::Tubes;
The sequence makes no assumption as to the input record, although the first element in the provided list might do.
Note that the last tube in the sequence might actually return an output record with an
undef
or otherwise false value (Perl-wise). To cope with this, when called in list context, the iterator is guaranteed to either return one single output record, or the empty list when the iterator is exhausted.The suggested idiom for taking items from the iterator is then the following:
my $it1 = $sequence1->($input_record)->{iterator}; while (my ($output_record) = $it1->()) { # work with $output_record here, it's your output record! } # if you're waiting for a single output record, use if my $it2 = $sequence2->($input_record)->{iterator}; if (my ($output_record) = $it2->()) { # work with $output_record here, it's your output record! }
BUGS AND LIMITATIONS
Report bugs either through RT or GitHub (patches welcome).
AUTHOR
Flavio Poletti <polettix@cpan.org>
COPYRIGHT AND LICENSE
Copyright (C) 2016 by Flavio Poletti <polettix@cpan.org>
This module is free software. You can redistribute it and/or modify it under the terms of the Artistic License 2.0.
This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose.